X.50九、PKCS文件格式介紹

ASN.1 - 數據結構描述語言

引用自Wikihtml

ASN.1 is a standard interface description language for defining data structures that can be serialized and deserialized in a cross-platform way.

也就是說ASN.1是一種用來定義數據結構的接口描述語言,它不是二進制,也不是文件格式,看下面的例子你就會明白了:git

FooQuestion ::= SEQUENCE {
    trackingNumber INTEGER,
    question       IA5String
}

這段代碼定義了FooQuestion的數據結構,下面是FooQuestion這個數據接口的某個具體的數據:web

myQuestion FooQuestion ::= SEQUENCE {
    trackingNumber     5,
    question           "Anybody there?"
}

ASN.1用在不少地方好比下面要講的X.509PKCS group of cryptography standards安全

文件編碼格式

DER編碼格式

引用自Wikibash

ASN.1 is closely associated with a set of encoding rules that specify how to represent a data structure as a series of bytes

意思是ASN.1有一套關聯的編碼規則,這些編碼規則用來規定如何用二進制來表示數據結構,DER是其中一種。數據結構

把上面的FooQuestion的例子用DER編碼則是(16進制):ide

30 13 02 01 05 16 0e 41 6e 79 62 6f 64 79 20 74 68 65 72 65 3f

翻譯過來就是:編碼

30 — type tag indicating SEQUENCE
13 — length in octets of value that follows
  02 — type tag indicating INTEGER
  01 — length in octets of value that follows
    05 — value (5)
  16 — type tag indicating IA5String 
     (IA5 means the full 7-bit ISO 646 set, including variants, 
      but is generally US-ASCII)
  0e — length in octets of value that follows
    41 6e 79 62 6f 64 79 20 74 68 65 72 65 3f — value ("Anybody there?")

看到這裏你應該對DER編碼格式有一個比較好的認識了。加密

PEM編碼格式

引用自Wikispa

Privacy-Enhanced Mail (PEM) is a de facto file format for storing and sending cryptographic keys, certificates, and other data, based on a set of 1993 IETF standards defining "privacy-enhanced mail."

PEM是一個用來存儲和發送密碼學key、證書和其餘數據的文件格式的事實標準。許多使用ASN.1的密碼學標準(好比X.509PKCS)都使用DER編碼,而DER編碼的內容是二進制的,不適合與郵件傳輸(早期Email不能發送附件),所以使用PEM把二進制內容轉換成ASCII碼。文件內容的格式像下面這樣:

-----BEGIN label-----
BASE64Encoded
-----END label-----

label用來區份內容究竟是什麼類型,下面會講。

和PEM相關的RFC有不少,與本文內容相關的則是RFC7468,這裏面規定了不少label,不過要注意不是全部label都會有對應的RFC或Specification,這些label只是一種約定俗成。

PEM實際上就是把DER編碼的文件的二進制內容用base64編碼一下,而後加上-----BEGIN label-----這樣的頭和-----END label-----這樣的尾,中間則是DER文件的Base64編碼。

咱們能夠經過下面的方法驗證這個結論,先生成一個RSA Private Key,編碼格式是PEM格式:

openssl genrsa -out key.pem

查看一下文件內容,能夠看到label是RSA PRIVATE KEY

-----BEGIN RSA PRIVATE KEY-----
BASE64Encoded
-----END RSA PRIVATE KEY-----

而後咱們把PEM格式轉換成DER格式:

openssl rsa -in key.pem -outform der -out key.der

若是你這個時候看一下文件內容會發現都是二進制。而後咱們把DER文件的內容Base64一下,會看到內容和PEM文件同樣(忽略頭尾和換行):

base64 -i key.der -o key.der.base64

證書、密碼學Key格式

上面講到的PEM是對證書、密碼學Key文件的一種編碼方式,下面舉例這些證書、密碼學Key文件格式:

X.509證書

引用自Wiki

In cryptography, X.509 is a standard defining the format of public key certificates. X.509 certificates are used in many Internet protocols, including TLS/SSL, which is the basis for HTTPS, the secure protocol for browsing the web.

X.509是一個Public Key Certificates的格式標準,TLS/SSL使用它,TLS/SSL是HTTPS的基礎因此HTTPS也使用它。而所謂Public Key Certificates又被稱爲Digital CertificateIdentity Certificate

An X.509 certificate contains a public key and an identity (a hostname, or an organization, or an individual), and is either signed by a certificate authority or self-signed.

一個X.509 Certificate包含一個Public Key和一個身份信息,它要麼是被CA簽發的要麼是自簽發的。

下面這種張圖就是一個X.509 Certificate:

事實上X.509 Certificate這個名詞一般指代的是IETF的PKIX Certificate和CRL Profile,見RFC5280。因此當你看到PKIX Certificate字樣的時候能夠認爲就是X.509 Certificate。

PKCS系列

引用自Wiki

In cryptography, PKCS stands for "Public Key Cryptography Standards"

前面提到的X.509是定義Public Key Certificates的格式的標準,看上去和PKCS有點像,但實際上不一樣,PKCS是Public Key密碼學標準。此外Public-Key Cryptography雖然名字看上去只涉及Public Key,實際上也涉及Priviate Key,所以PKCS也涉及Private Key。

PKCS一共有15個標準編號從1到15,這裏只挑講PKCS #一、PKCS #八、PKCS #12。

PKCS #1

PKCS #1,RSA Cryptography Standard,定義了RSA Public Key和Private Key數學屬性和格式,詳見RFC8017

PKCS #8

PKCS #8,Private-Key Information Syntax Standard,用於加密或非加密地存儲Private Certificate Keypairs(不限於RSA),詳見RFC5858

PKCS #12

PKCS #12定義了一般用來存儲Private Keys和Public Key Certificates(例如前面提到的X.509)的文件格式,使用基於密碼的對稱密鑰進行保護。注意上述Private Keys和Public Key Certificates是複數形式,這意味着PKCS #12文件其實是一個Keystore,PKCS #12文件能夠被用作Java Key Store(JKS),詳見RFC7292

若是你用本身的CA所簽發了一個證書,運行下列命令能夠生成PKCS #12 keystore:

openssl pkcs12 -export \
  -in <cert> \
  -inkey <private-key> \
  -name my-cert \
  -caname my-ca-root \
  -CAfile <ca-cert> \
  -chain
  -out <pkcs-file>

PKCS #12通常不導出PEM編碼格式。

PEM格式速查

當你不知道你的PEM文件內容是什麼格式的能夠根據下面查詢。

X.509 Certificate

RFC7468 - Textual Encoding of Certificates

-----BEGIN CERTIFICATE-----
BASE64Encoded
-----END CERTIFICATE-----

X.509 Certificate Subject Public Key Info

RFC7468 - Textual Encoding of Subject Public Key Info

-----BEGIN PUBLIC KEY-----
BASE64Encoded
-----END PUBLIC KEY-----

PKCS #1 Private Key

沒有RFC或權威Specification,該格式有時候被稱爲traditional format、SSLeay format(見SO

-----BEGIN RSA PRIVATE KEY-----
BASE64Encoded
-----END RSA PRIVATE KEY-----

PKCS #1 Public Key

同上沒有RFC或權威Specification

-----BEGIN RSA PUBLIC KEY-----
BASE64Encoded
-----END RSA PUBLIC KEY-----

PKCS #8 Unencrypted Private Key

RFC7468 - One Asymmetric Key and the Textual Encoding of PKCS #8 Private Key Info

-----BEGIN PRIVATE KEY-----
BASE64Encoded
-----END PRIVATE KEY-----

PKCS #8 Encrypted Private Key

RFC7468 - Textual Encoding of PKCS #8 Encrypted Private Key Info

-----BEGIN ENCRYPTED PRIVATE KEY-----
BASE64Encoded
-----END ENCRYPTED PRIVATE KEY-----

Private Key操做命令

生成

生成PKCS #1格式的RSA Private Key

openssl genrsa -out private-key.p1.pem 2048

轉換

PKCS #1 -> Unencrypted PKCS #8

openssl pkcs8 -topk8 -in private-key.p1.pem -out private-key.p8.pem -nocrypt

PKCS #1 -> Encrypted PKCS #8

openssl pkcs8 -topk8 -in private-key.p1.pem -out private-key.p8.pem

過程當中會讓你輸入密碼,你至少得輸入4位,因此PKCS #8相比PKCS #1更安全。

PKCS #8 -> PKCS #1

openssl rsa -in private-key.p8.pem -out private-key.p1.pem

若是這個PKCS #8是加密的,那麼你得輸入密碼。

Public Key操做命令

從PKCS #1/#8提取

提取指的是從Private Key中提取Public Key,openssl rsa同時支持PKCS #1和PKCS #8的RSA Private Key,惟一的區別是若是PKCS #8是加密的,會要求你輸入密碼。

提取X.509格式RSA Public Key

openssl rsa -in private-key.pem -pubout -out public-key.x509.pem

提取PKCS #1格式RSA Public Key

openssl rsa -in private-key.pem -out public-key.p1.pem -RSAPublicKey_out

從X.509證書提取

openssl x509 -in cert.pem -pubkey -noout > public-key.x509.pem

轉換

X.509 RSA Public Key -> PKCS #1 RSA Public Key

openssl rsa -pubin -in public-key.x509.pem -RSAPublicKey_out -out public-key.p1.pem

PKCS #1 RSA Public Key -> X.509 RSA Public Key

openssl rsa -RSAPublicKey_in -in public-key.p1.pem -pubout -out public-key.x509.pem

參考資料

相關文章
相關標籤/搜索