對(duì)稱加密算法
非對(duì)稱加密算法
非對(duì)稱加密:加密密鑰與解密密鑰成對(duì)出現(xiàn)间学,一般為私鑰和公鑰囱皿。私鑰用于簽名或加密荆姆;公鑰用于驗(yàn)簽或解密蔼囊。
RSA
密鑰生成
- OpenSSL明文生成命令如下:
## generate private key without password
openssl genrsa -out rsa.key 2048
## export public key
openssl rsa -in rsa.key -pubout -out rsa.pub
- 明文私鑰內(nèi)容如下:BEGIN RSA PRIVATE KEY為PKCS#1格式
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEArzMYu9B07EwgLma0c+BK+vGAGrVqvRnhxPr4o7NVAfCqKe6V
7evym0ClkCK4NJ7s8bHJjmTxBXIpZuPOJBJhG2H0EALFap7sfzSxbbHIUkoJDO/c
kuo7enZ/R5UIs/esuua5/oiPlx3XY/9+OHviuyCtCPy0dFi7j9TNxstsUj7eXs+Y
r1TC+bA7CointNqi9TDwU3cM74jdgUrIU/uLtqL2mB22RCa80FfcURp7tQYVDyPO
nHex4ijjjyl1zi26YI1kxZf8dRlRoFfGTayrS/8Txp0KqGKEsLJyYQ8DeuEhW9gW
/Ka340ZC7ObVMqTzMJ7pzxyWmbRqHOIlO54jxQIDAQABAoIBAB2gHEyWAU97x+1Q
vK7jfIpWj/z0NGppl/3BGo5D4toDIiMZDw0+WrXaBqUK2e87+IEeOSD0/LSZC1s0
pkT/PqBsveJ/NXbEDOWtuVr9NwyDLGidnsTRCuG4a+lk0CXueazZGxZpbS52g1eL
eoJ+oGZYLipY4QLThlPZ/jnhaB238CfAQ+KfkkxdJcPEJWzONalWsTrb0RK+0WHZ
sgwJwCn9zBECZYNkHKKV0G1/TOyslZTZwo8aXCsEtwQmtwqtuYEaPCTrJ8YPpjoD
HjEdt6sUcCJd98aHxJ9zuABgDlq7NZAsAhgmdPPcnXu5xSFgFw7yPj/6UDgZxtcb
5VkSMsECgYEA2a9nKL241eMnqJ9/dBE84fNFEg0C9hNEljGr8sxilg0cs3nk4v6P
GRVcl6fjmRm6bIUzHPmFFFBOzr9JIlKv71II1S1Dn4l0gIuT5epPB1OlinBCU+Ur
jjhuZ3UOeZQ3LF9nKeDqn6jDjY6jXCQRK9xqKmzZ2yCUGrwYKpa0JskCgYEAzgla
B+y5bWPLYC0sv76yz5I+yTfIl7PAO6clgzSgBhHNFkjPA0eWcA/AA9tZS5Nz5MB5
ACiKN82dmnOedkkpJg29CTc7KttNTie5A7n+reKKV8qMMSM7I/MbQn/j7GIrW/uG
6WiZveXtK7o4jLZOGPE2nTx0iFGrrUjLK3TURx0CgYAdD3J5GOLNAvcvZqOQLiDv
lRdacow7p5TXbCglUK20lGmJeDNbLlqSIazrvgj/TlT52cpaCuF+Nb5fkV/FCj7c
dxogw1ssuB/qbTfAUMheFQebdKMWKhjncpcijpjxGB1Jei7+gz0vNUtt4WXjjhkQ
vusZYNCwlSfQbd3YCahhKQKBgC/xeSOy8AsGV8LPgEQ2CcHHVBjahDDYwPigklgP
nNUMu15eHt2ygM0evR2oowS1ERi/uOhShqcpj2zrTopTx+F0/PHyCjCUy05Oa/z0
ANFRj8OR/EFK424gGc3FmLHevhwvUVtq3auUnzW3pYUIvu+K4ZyA/tThvEMcVzqL
ewH5AoGBAKx3QRwdnCYFZTV26DO1LqjT3b2AbGBtM18u2mPwf593qJt3oJdJMGii
LGkGNZgCm88gMN/sY+chSJumlCHToFHLiovVIManpkv0Y7sXHw6TUeSjg5hB84b6
If/YzYcoFIpi1uKGVMSTnEdzLx1sjqM00qsVZz9cz8f71TMOOsQx
-----END RSA PRIVATE KEY-----
- 公鑰內(nèi)容如下:BEGIN PUBLIC KEY為PKCS#8格式
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArzMYu9B07EwgLma0c+BK
+vGAGrVqvRnhxPr4o7NVAfCqKe6V7evym0ClkCK4NJ7s8bHJjmTxBXIpZuPOJBJh
G2H0EALFap7sfzSxbbHIUkoJDO/ckuo7enZ/R5UIs/esuua5/oiPlx3XY/9+OHvi
uyCtCPy0dFi7j9TNxstsUj7eXs+Yr1TC+bA7CointNqi9TDwU3cM74jdgUrIU/uL
tqL2mB22RCa80FfcURp7tQYVDyPOnHex4ijjjyl1zi26YI1kxZf8dRlRoFfGTayr
S/8Txp0KqGKEsLJyYQ8DeuEhW9gW/Ka340ZC7ObVMqTzMJ7pzxyWmbRqHOIlO54j
xQIDAQAB
-----END PUBLIC KEY-----
- OpenSSL密文生成命令如下:
## generate rsa private key with password
openssl genrsa -aes256 -out name_private.key 2048
- 密文如下:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,6BD39B13ECA6BE46F418ECC341EEC626
p4TtCgJUP7Ik/f2xqJrJ3zfbGiA49T3Vrf9naKSYrZawGVhqYxRu+fiXePxKc25L
8rdnwCiF7x2xtR9uNWcWlFIe76KlPqrFMqBzVrEloOb0bM9TvZ06ZsYE6DrlH2xj
1NLzKz9I3CQ9M/VZIHInzvm7J1vFPFwSH5NSjq3oIVnMgfPMzaq5DCBYIxJ4nOEm
fGRx9bXnTzpIPCR6MrgmZiWzEt3akgkKSzQlfEEOLWfjEDBvJmuLO20CIfj+Q8Y6
rTMroud7sZb+FFDHAB3BolEp2Bqfi0YQJ8rMKTl+On3QFdBQD+v9jcTurqhD1C47
3KHieg18ZN2OxNTHHJMo0A1VEent6lvBSHIPKtgyUBP87+nUPsWoBDQV+zoL3pCP
O4zlY35WEt6BU+ImupkNNjZ70Sgfr3hUdXN3ZZi2rWUqGABzUpBREF9UuQVuqOeO
lpswWKMKQIXuvbZ70OdZ6JsUBMdeEIZSvEDeez85ef2GwuB6IvJtxmWNf4POiJxJ
oNponrYCh6RatQLDKgg0iqE2fkyq6QoKN8mFIHNwG7LS5CsSCiNzsj1lhl4pm2eB
5NQrInKa/sDFN1uFmtrWGw1bhyJdUPGPhaw5Xb1DRh1dbxooieEaCysuu+RpZpqc
AVwhrKf2IB2N82mEiQfD0FwJ4FGtBhlAmtMHHjtlDmbh1qzOYs1wUKpPY8C72fza
XwfS8kMdac3HWJc4osJ+/YoQv9cQtQX/DwiA/86nxRiogjbtDYERneu2ucxnzFrV
i0l9frX2qvkuXWArlT9+0zFZA3fTF0fP5j2mrf8tdTE+OdAVqRW50l2JiVId8qUv
2D5ygiHn1h+zPreeckA1386HMYwPirHcr/JpzrI5R+hCgXGEVi2GQISRjsVa2sqS
hNEirQFe7M6HPgtPaXcjKm/R8MY2aVHI3irTccXvIjDo2GCb85ZQFLqdQOE3N+h7
xrdcDaNZV6K6ZcudUsLiiH6gjXeiTL9VeSJQdyJ5mDJpEl9297JU7CbrRwndUgTV
qJ6Q5s9r158Bb0aLQwYFx0FEwqIiQB+tZoJ1e9+H8jNuRvDn35thMrOw+QcsMsT8
7QHL741jjcB51610afi5Zb2xhUKiWwrJLLKfp+e+4B3aFnhBm8anRcwBaYaF4OWK
4O8vialNxUelI6qJqyjb9sS/9G+YCmWjkvO/Wc7CcZ2dag0cxvyV+XZllUfFaZpN
5KbIH+zv+6pa2GyeePWekvsYQstXB43lKDYYjcO89SVGwEXGw1W7TlJI9SPZl3eR
FcN/O7CEcZfA17XDsS7u6FZgLfRlLeqSpRhRxgAuB7XpdwKVazPc6fVr48h6rH/M
Po9+wDUId7wrdAnxZgETpcIVgISpszfCYGKuYc1tZXaBDZxivHCV4oTdDp9uFwF1
QB6kZIcQ2evqDLtQt5jRNHl7792RNiwWIZd66WTV2fie2YHoF42lhj7/AdbI+nDx
Wzt0bvV5/lwsrnSZbLLTGwdxs/eoDrhhuCBeChoeXsxwm0yCu7cy8Ogqv/LXu5m8
Nm7HkkZ0eldHiFhOiRSDRCfzJwCBmZt6wPnvgsslBwYA8MCN5qI2a3nxMz5rxip/
-----END RSA PRIVATE KEY-----
- 其他命令
## view the public key
openssl rsa -pubin -in name.pub -noout -text
## remove the password of the private key
openssl rsa -in name.key -out name_plain.key
## view private key with interactive mode
openssl rsa -in name.key -noout -text
## view private key with a password file
openssl rsa -in name.key -noout -text -passin file:path/to/password
密鑰分析
OpenSSL命令生成的私鑰格式默認(rèn)為PEM焚志,所以在進(jìn)一步分析私鑰之前,先大致了解一些術(shù)語(yǔ)畏鼓。
- PEM
- DER
- PKCS#1
- PKCS#8
PKCS#1
RSA的PKCS#1格式的私鑰結(jié)構(gòu)如下:其中比較重要的都是與RSA算法相關(guān)的整數(shù)酱酬,RSA算法細(xì)節(jié)不在此文討論。
RSAPrivateKey ::= SEQUENCE {
version Version, //版本
modulus INTEGER, // RSA合數(shù)模 n
publicExponent INTEGER, //RSA公開(kāi)冪 e
privateExponent INTEGER, //RSA私有冪 d
prime1 INTEGER, //n的素?cái)?shù)因子p
prime2 INTEGER, //n的素?cái)?shù)因子q
exponent1 INTEGER, //值 d mod (p-1)
exponent2 INTEGER, //值 d mod (q-1)
coefficient INTEGER, //CRT系數(shù) (inverse of q) mod p
otherPrimeInfos OtherPrimeInfos OPTIONAL
}
首先云矫,我們可以通過(guò)以下Go代碼將PEM格式的私鑰轉(zhuǎn)換為DER格式的字節(jié)串膳沽,并解析為可用于分析的私鑰結(jié)構(gòu)體:
func getPrivKey(keyFile string) (*rsa.PrivateKey, error) {
key, err := ioutil.ReadFile(keyFile)
if err != nil {
return nil, err
}
block, _ := pem.Decode([]byte(key))
if block == nil {
return nil, fmt.Errorf("failed to decode pem data")
}
priKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
fmt.Println(priKey.N.Bytes()) // 模數(shù)N
eBytes := make([]byte, 8)
binary.BigEndian.PutUint64(eBytes, uint64(priKey.E)) // 公有冪,一般為65537
fmt.Println(eBytes)
fmt.Println(priKey.D.Bytes()) // 私有冪
fmt.Println(priKey.Primes[0].Bytes()) // n的素?cái)?shù)因子p
fmt.Println(priKey.Primes[0].Bytes()) // n的素?cái)?shù)因子q
fmt.Println(priKey.Precomputed.Dp.Bytes()) //值 d mod (p-1)
fmt.Println(priKey.Precomputed.Dq.Bytes()) //值 d mod (q-1)
fmt.Println(priKey.Precomputed.Qinv.Bytes()) // CRT系數(shù) (inverse of q) mod p
return priKey, nil
}
或者也可以通過(guò)ASN.1 JS Decoder對(duì)DER進(jìn)行分析让禀,為了方便挑社,我們直接采用第二種方式分析,如下:
image.png
其中巡揍,模數(shù)N部分如下痛阻,其他類似:
a. 02: tag
b. 82 – 81: 代表長(zhǎng)度用1byte表示,82代表長(zhǎng)度用2byte表示(此字節(jié)部分tag后不存在)
c. 0101: length 2bytes表示
d. 00: 在modulus數(shù)據(jù)前添加00腮敌,原因未知阱当,請(qǐng)知情道友告知俏扩。
e. 模數(shù)N