生成RSA密钥对有两个工具:
#通过ssh-keygen生成的私钥是pkcs1格式,但公钥是ssh特有格式(不是pkcs8也不是pkcs1)
ssh-keygen -t rsa -b 1024
#通过openssl生成密钥对,默认私钥是pkcs1格式,不输出公钥(因为公钥可以通过私钥导出)
openssl genrsa -out rsa_private_key.pem 1024
openssl也可以在制作申请证书用的csr:
openssl req -x509 -days 365 -newkey rsa:2048 -keyout private.pem -out req_csr.pem -nodes
# 用ssh-keygen输出ssh格式的公钥,这个格式比较特殊,只适用于ssh的场景
ssh-keygen -y -f priKey.pem > sshPubkey.pub
# openssl默认输出的是pkcs8格式的公钥
openssl rsa -pubout -in rsa_key.private -out rsa_key.public
将OpenSSH格式公钥转换成OpenSSL的pkcs1格式公钥
ssh-keygen -e -m PEM -f ssh_PubKey.pub > ssl_PubKey.pem
#-m参数支持 PEM,PKCS8,RFC4716
将OpenSSL的pkcs8格式公钥转换成OpenSSH的格式公钥
ssh-keygen -i -m PKCS8 -f rsa_public_key.pem > id_rsa.pub
先说一下区别,
PKCS1是标准RSA私钥的格式规范(采用ASN1语法格式);
PKCS8是对加密后的PKCS1私钥进行了描述,等于描述+PKCS1私钥(同样采用ASN1语法格式)
通俗点讲吧,就是:
PKCS1是一把钥匙,PKCS8就是把这个钥匙放到一个盒子里,并在盒子上贴个标签对这把钥匙做了说明,比如采用的是什么算法,密钥长度等,所以PKCS8不仅仅支持RSA算法,还支持其他算法的密钥。说白了,就是给这个钥匙捆绑了一个说明书,从而这个盒子不仅仅可装PKCS1的钥匙,还可以装其他类型的钥匙
这篇文章网上分析的比较透彻:
PRESS.one
java中的加解密用的包,默认生成的是私钥pkcs1,公钥pkcs8
最早openssl生成的公钥私钥默认都是pkcs1格式的,但是在后来的版本中,公钥默认为了pkcs8格式(私钥还是pkcs1格式,或许是为了迎合java吧,个人猜测)
将pkcs1格式的私钥转为pkcs8格式
注:openssh和openssl的私钥都默认是pkcs1结构的pem格式
openssl pkcs8 -topk8 -inform PEM -in id_rsa_cert -outform PEM -nocrypt -out id_rsa_cert_pkcs8.pem
将PKCS8格式私钥再转换为PKCS1格式
openssl rsa -in pkcs8.pem -out pkcs1.pem
将pkcs8公钥转pkcs1公钥
openssl rsa -pubin -in rsa_pub_pkcs8.pem -RSAPublicKey_out -out rsa_pub_pkcs1.pem
将pkcs1公钥转换为pkcs8公钥
openssl rsa -RSAPublicKey_in -in pub_pkcs1.pem -pubout -out pub_pkcs8.pem
openssl 1.1.1+ 版本增加了对SM2 的支持,所以可以使用openssl来生成SM2密钥对
# 检查openssl版本是否支持sm2
openssl ecparam -list_curves | grep SM2
# 生成ec参数:ec参数其实包含了ec参数和私钥
openssl ecparam -out ec_param.pem -name SM2 -param_enc explicit -genkey
ec_param.pem内容如下:
-----BEGIN EC PARAMETERS-----
MIHgAgEBMCwGByqGSM49AQECIQD+/wAAAAD/
/zBEBCD+/wAAAAD//AQgKOn6np2f
XjRNWp5Lz2UJp/OXifUVq4+S3by9QU2UDpMEQQQyxK4sHxmBGV+ZBEZqOcmUj+ML
v/JmC+FxWkWJM0x0x7w3NqL09necWb3O42tpIVPQqYd8xipHQALfMuUhOfCgAiEA
/v///3ID32shxgUrU7v0CTnVQSMCAQE=
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MIIBUQIBAQQg2EJXgrXjC6iwwCCW5qbR9kwVcp6Gd164ElDPKyipiO2ggeMwgeAC
AQEwLAYHKoZIzj0BAQIhAP7/AAAAAP//
MEQEIP7/AAAAAP/8BCAo6fqenZ9eNE1a
nkvPZQmn85eJ9RWrj5LdvL1BTZQOkwRBBDLEriwfGYEZX5kERmo5yZSP4wu/8mYL
4XFaRYkzTHTHvDc2ovT2d5xZvc7ja2khU9Cph3zGKkdAAt8y5SE58KACIQD+
cgPfayHGBStTu/QJOdVBIwIBAaFEA0IABOJVD/jik5D5XVCQ
+2tX23HR74N4URgoRtSa9gx0/kV9rasQA7XrQQ9Y543MfFDdblvJRKqajnmpmgf+
1smw60E=
-----END EC PRIVATE KEY-----
# 查看和检查ec参数
openssl ecparam -in ec_param.pem -text
openssl ecparam -in ec_param.pem -check
# 导出私钥:pkcs8格式
openssl pkcs8 -topk8 -inform PEM -in ec_param.pem -outform pem -nocrypt -out pri_key_pkcs8.pem
# 导出公钥:pkcs8格式
openssl ec -in ec_param.pem -pubout -out pub_key.pem