国密(1) - 私钥Key文件( PEM格式)编解码方法

2023-11-11

    详细的PEM文件格式解析

    PEM文件,是按照私钥的ASN.1的格式(RFC5208/5915/5480)进行DER编码后输出二进制串的基础上,再进行Base64的编码,也就是每6个bit为一组,生成一个ascii码字符,需要4组6个bit,凑出4个ascii码字符;如果不足4组,需要补零,补零部分编码为“=”等号字符;


下面是一个私钥Key文件编码后的Base64文件:具体内容按照管理员要求删除
 

可以用开源工具openssl解码PEM文件:openssl ec -in SE1.key.pem -text  
#openssl ec -in SE1.key.pem -text
read EC key
Private-Key: (256 bit)
priv:
    4e:a8:8c:46:51:00:7b:36:a6:4c:8c:4e:bb:9d:b1:
    1f:64:91:27:d7:26:bf:e5:b9:bc:eb:39:54:9e:61:
    a1:fa
pub:
    04:ca:0b:7e:5a:fa:07:34:d1:84:4b:2a:eb:5a:0a:
    09:2c:4a:71:68:9a:33:8d:12:d3:78:f1:9b:39:78:
    5d:cc:c1:ba:58:69:67:71:4d:a7:a7:e7:3d:b3:99:
    6b:72:a4:bf:cd:78:a5:0f:55:fc:64:73:cd:2f:a7:
    7b:90:dc:d7:7f
ASN1 OID: SM2
writing EC key
 

其实也可以自己写python脚本来完成PEM文件的Base64的编码或解码:

import base64

下面从16进制的私钥keyDER编码后的码流去进行Base64编码生成PEM文本:

S = bytes().fromhex('308187020100301306072a8648ce3d020106082a811ccf5501822d046d306b02010104204ea88c4651007b36a64c8c4ebb9db11f649127d726bfe5b9bceb39549e61a1faa14403420004ca0b7e5afa0734d1844b2aeb5a0a092c4a71689a338d12d378f19b39785dccc1BA586967714DA7A7E73DB3996B72A4BFCD78A50F55FC6473CD2FA77B90DCD77F')
e64 = base64.b64encode(S)
print(e64)

下面从PEM文本进行Base64解码,生成16进制的私钥keyDER编码后的码流:

e64 = b'MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgTqiMRlEAezamTIxOu52xH2SRJ9cmv+W5vOs5VJ5hofqhRANCAATKC35a+gc00YRLKutaCgksSnFomjONEtN48Zs5eF3MwbpYaWdxTaen5z2zmWtypL/NeKUPVfxkc80vp3uQ3Nd/'
d64 = base64.b64decode(e64)
print(d64.hex())

Base64文件解码后,可以读出私钥和公钥内容,下面是Base64解码后的16进制码流,对应ASN.1 DER 编码/解码说明::
308187 (30 代表sequence,81:8代表内容长度超过了127,1代表后面有一个字节描述长度,87代表sequence内容的长度)
020100 (02整型;01;长度;取值是00)
3013  (30 代表sequence,13:代表长度是19字节)
0607   (06代表object id,07代表长度)
2a8648ce3d0201 (1.2.840.10045.2.1 ecPublicKey (ANSI X9.62 public key type))
0608    (06代表object id,07代表长度)
2a811ccf5501822d  DER编码的OID:1.2.156.10197.1.301(1.2.156.10197.1.301 sm2ECC (China GM Standards Committee))

046d (04代表OCTET STRING,6d是长度109)
306b (30代表sequence,6b代表长度107)
020101 (02代表整数,01代表长度1,取值是01 ecPrivkeyVer1)
0420 (04代表OCTET STRING,20是长度32)
4ea88c4651007b36a64c8c4ebb9db11f649127d726bfe5b9bceb39549e61a1fa (32字节私钥)
a1 44  (a Context-specific+constucted 1代表 publicKey  [1] 里面的数字tag [1];44代表长度68)
0342  03代表bitstring,42代表长度66
00 padding
04 (04代表是未压缩的公钥,The first octet of the OCTET STRING indicates whether the key is compressed or uncompressed.  The uncompressed form is indicated
        by 0x04 and the compressed form is indicated by either 0x02 or 0x03 (see 2.3.3 in [SEC1]).)
ca0b7e5afa0734d1844b2aeb5a0a092c4a71689a338d12d378f19b39785dccc1BA586967714DA7A7E73DB3996B72A4BFCD78A50F55FC6473CD2FA77B90DCD77F(64字节公钥X+Y,各32字节)

下面是私钥key文件的ASN.1格式描述:
PrivateKeyInfo ::= SEQUENCE {
        version                   Version,
        privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
        privateKey                PrivateKey,
        attributes           [0]  IMPLICIT Attributes OPTIONAL }

      Version ::= INTEGER

      PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier

      PrivateKey ::= OCTET STRING

      Attributes ::= SET OF Attribute

私钥内容的具体解释取决与算法:
privateKey is an octet string whose contents are the value of the
private key. The interpretation of the contents is defined in the
registration of the private-key algorithm. For an RSA private
key, for example, the contents are a BER encoding of a value of
type RSAPrivateKey.

   ECPrivateKey ::= SEQUENCE {
     version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
     privateKey     OCTET STRING,
     parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
     publicKey  [1] BIT STRING OPTIONAL
   }
   
     The parameter for id-ecPublicKey is as follows and MUST always be
   present:

     ECParameters ::= CHOICE {
       namedCurve         OBJECT IDENTIFIER
       -- implicitCurve   NULL
       -- specifiedCurve  SpecifiedECDomain
     }
       -- implicitCurve and specifiedCurve MUST NOT be used in PKIX.
       -- Details for SpecifiedECDomain can be found in [X9.62].
       -- Any future additions to this CHOICE should be coordinated
       -- with ANSI X9.


ALGORITHM ::= CLASS { 
&Type OPTIONAL, 
&id OBJECT IDENTIFIER UNIQUE } 
WITH SYNTAX { 
[PARMS &Type] 
IDENTIFIED BY &id } 

AlgorithmIdentifier{ALGORITHM:SupportedAlgorithms} ::= SEQUENCE { 
algorithm ALGORITHM.&id({SupportedAlgorithms}), 
parameters ALGORITHM.&Type({SupportedAlgorithms}{@algorithm}) OPTIONAL, 
... } 
 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

国密(1) - 私钥Key文件( PEM格式)编解码方法 的相关文章

随机推荐