“ BEGIN RSA PRIVATE KEY”和“ BEGIN PRIVATE KEY”之间的区别


150

嗨,我正在编写一个程序,该程序从.pem文件导入私钥并创建私钥对象以供以后使用..我面临的问题是某些pem文件头以

-----BEGIN PRIVATE KEY-----

而其他人开始

-----BEGIN RSA PRIVATE KEY-----

通过搜索,我知道第一个是PKCS#8格式化的,但是我不知道另一个属于什么格式。

Answers:


183

请参阅https://polarssl.org/kb/cryptography/asn1-key-structures-in-der-pem(在页面上搜索“ BEGIN RSA PRIVATE KEY”)(后代的存档链接,以防万一)。

BEGIN RSA PRIVATE KEY是PKCS#1,仅是RSA密钥。它本质上只是PKCS#8中的关键对象,而前面没有版本或算法标识符。BEGIN PRIVATE KEY是PKCS#8,表示密钥类型本身包含在密钥数据中。从链接:

未加密的PKCS#8编码的数据以标签开头和结尾:

-----BEGIN PRIVATE KEY-----
BASE64 ENCODED DATA
-----END PRIVATE KEY-----

在base64编码的数据中,存在以下DER结构:

PrivateKeyInfo ::= SEQUENCE {
  version         Version,
  algorithm       AlgorithmIdentifier,
  PrivateKey      BIT STRING
}

AlgorithmIdentifier ::= SEQUENCE {
  algorithm       OBJECT IDENTIFIER,
  parameters      ANY DEFINED BY algorithm OPTIONAL
}

因此,对于RSA私钥,OID为1.2.840.113549.1.1.1,并且有一个RSAPrivateKey作为私钥密钥数据位串。

与相对BEGIN RSA PRIVATE KEY,始终指定RSA密钥,因此不包含密钥类型OID。BEGIN RSA PRIVATE KEYPKCS#1

RSA私钥文件(PKCS#1)

RSA私钥PEM文件专用于RSA密钥。

它以标签开头和结尾:

-----BEGIN RSA PRIVATE KEY-----
BASE64 ENCODED DATA
-----END RSA PRIVATE KEY-----

在base64编码的数据中,存在以下DER结构:

RSAPrivateKey ::= SEQUENCE {
  version           Version,
  modulus           INTEGER,  -- n
  publicExponent    INTEGER,  -- e
  privateExponent   INTEGER,  -- d
  prime1            INTEGER,  -- p
  prime2            INTEGER,  -- q
  exponent1         INTEGER,  -- d mod (p-1)
  exponent2         INTEGER,  -- d mod (q-1)
  coefficient       INTEGER,  -- (inverse of q) mod p
  otherPrimeInfos   OtherPrimeInfos OPTIONAL
}

因此,除了这两种格式以外,是否还有其他格式可以使用?是否可以从标题中确定格式?
monim

1
我认为在sonic的答案中给出的任何私钥标签都是公平的游戏。
杰森C

对于RSA密钥,PKCS#1包含CRT参数,而PKCS#8没有。您可以通过查看尺寸来确认。即使添加了更多的标头,PKCS#8也较小。如果您关心性能,请使用PKCS#1。我的测试显示速度提高了3倍。
ZZ编码器2014年

5
@ZZCoder,能否请您提供一些有关如何生成密钥和测试性能的详细信息?openssl genpkey -algorithm RSA -out key.pem生成不包含CRT参数的PKCS#8密钥。
Vadim Kuznetsov'5

5
要生成PKCS#1密钥,openssl genrsa可以使用该命令。使用openssl req同时生成私钥和CRT将结束与一个PKCS#8键。在genpkey手动状态The use of the genpkey program is encouraged over the algorithm specific utilities because additional algorithm options and ENGINE provided algorithms can be used.。但是某些软件(mysql)只能使用PKCS#1密钥。从转换PKCS#8PKCS#1是可以做到的openssl rsa -in key.pem -out key.pem。可以使用进行其他转换openssl pkey -in key.pem -out key.pem
保罗·托比亚斯

28

看一看<openssl/pem.h>。它给出了可能的BEGIN标记。

复制以上链接中的内容以供快速参考:

#define PEM_STRING_X509_OLD "X509 CERTIFICATE"
#define PEM_STRING_X509     "CERTIFICATE"
#define PEM_STRING_X509_PAIR    "CERTIFICATE PAIR"
#define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE"
#define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST"
#define PEM_STRING_X509_REQ "CERTIFICATE REQUEST"
#define PEM_STRING_X509_CRL "X509 CRL"
#define PEM_STRING_EVP_PKEY "ANY PRIVATE KEY"
#define PEM_STRING_PUBLIC   "PUBLIC KEY"
#define PEM_STRING_RSA      "RSA PRIVATE KEY"
#define PEM_STRING_RSA_PUBLIC   "RSA PUBLIC KEY"
#define PEM_STRING_DSA      "DSA PRIVATE KEY"
#define PEM_STRING_DSA_PUBLIC   "DSA PUBLIC KEY"
#define PEM_STRING_PKCS7    "PKCS7"
#define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA"
#define PEM_STRING_PKCS8    "ENCRYPTED PRIVATE KEY"
#define PEM_STRING_PKCS8INF "PRIVATE KEY"
#define PEM_STRING_DHPARAMS "DH PARAMETERS"
#define PEM_STRING_DHXPARAMS    "X9.42 DH PARAMETERS"
#define PEM_STRING_SSL_SESSION  "SSL SESSION PARAMETERS"
#define PEM_STRING_DSAPARAMS    "DSA PARAMETERS"
#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
#define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
#define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY"
#define PEM_STRING_PARAMETERS   "PARAMETERS"
#define PEM_STRING_CMS      "CMS"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.