介紹

每個人都喜歡PEM和用於以便攜式格式保存加密密鑰和證書的ASN.1結構。好吧..如果他們真的被記錄下來,每個人都會這樣做。但是,找到每個DER或PEM格式文件中的結構是一個很大的壯舉。

由於我們需要這些信息,我們也會在這里分享,以幫助他人尋求知識和理解;)

ASN.1和DER編碼

在RSA,PKCS#1和SSL / TLS社區內ASN.1的分辨編碼規則(DER)編碼用於以便攜式格式表示密鑰,證書等。盡管ASN.1不是最容易理解的表示格式並且帶來了很多復雜性,但它確實有其優點。證書或密鑰信息存儲在ASN.1的二進制DER中,提供RSA,SSL和TLS的應用程序應處理DER編碼以讀取信息。

PEM文件

由於DER編碼導致編碼數據的真正二進制表示,因此設計了一種格式,以便能夠以可打印字符的編碼方式發送這些格式,以便您可以實際郵寄這些內容。我現在關注的格式是PEM格式。

我們將看到的大多數PEM格式的文​​件是由OpenSSL在生成或導出RSA私鑰或公鑰和X509證書時生成的。

本質上,PEM文件只是DER編碼數據的base64編碼版本。為了區分外部DER編碼字符串中的數據類型,數據周圍存在頁眉和頁腳。PEM編碼文件的示例是:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMYfnvWtC8Id5bPKae5yXSxQTt
+Zpul6AnnZWfI2TtIarvjHBFUtXRo96y7hoL4VWOPKGCsRqMFDkrbeUjRrx8iL91
4/srnyf6sh9c8Zk04xEOpK1ypvBz+Ks4uZObtjnnitf0NBGdjMKxveTq+VE7BWUI
yQjtQ8mbDOsiLLvh7wIDAQAB
-----END PUBLIC KEY-----

第一行和最后一行表示內部應該預期的DER格式。里面的數據是DER編碼信息的base64編碼版本。

格式

所以這一切都很好。但是在每個不同的文件中你應該期待什么結構?請看下面的不同格式的解釋。

RSA公鑰文件(PKCS#1)

RSA公鑰PEM文件特定於RSA密鑰。

它以標簽開頭和結尾:

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

在base64編碼數據中,存在以下DER結構:

RSAPublicKey ::= SEQUENCE {
    modulus           INTEGER,  -- n
    publicExponent    INTEGER   -- e
}

公鑰文件(PKCS#8)

由於RSA不是專門用於X509和SSL / TLS,因此PKCS#8形式提供了更通用的密鑰格式,它標識了公鑰的類型並包含相關數據。

它以標簽開頭和結尾:

-----BEGIN PUBLIC KEY-----
BASE64 ENCODED DATA
-----END PUBLIC KEY-----

在base64編碼數據中,存在以下DER結構:

PublicKeyInfo ::= SEQUENCE {
  algorithm       AlgorithmIdentifier,
  PublicKey       BIT STRING
}

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

因此,對於RSA公鑰,OID是1.2.840.113549.1.1.1,並且有一個RSAPublicKey作為PublicKey密鑰數據bitstring。

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
}

私鑰文件(PKCS#8)

由於RSA不是專門用於X509和SSL / TLS,因此PKCS#8形式的更通用密鑰格式可用於標識私鑰的類型並包含相關數據。

未加密的PKCS#8編碼數據以標簽開頭和結尾:

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

在base64編碼數據中,存在以下DER結構:

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

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

因此對於RSA私鑰,OID是1.2.840.113549.1.1.1並且存在RSAPrivateKey作為PrivateKey密鑰數據八位字節串。

加密的PKCS#8編碼數據以標簽開頭和結尾:

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

在base64編碼數據中,存在以下DER結構:

EncryptedPrivateKeyInfo ::= SEQUENCE {
  encryptionAlgorithm  EncryptionAlgorithmIdentifier,
  encryptedData        EncryptedData
}

EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier

EncryptedData ::= OCTET STRING

EncryptedData OCTET STRING是PKCS#8 PrivateKeyInfo(見上文)。

這有幫助嗎?