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

本文详细介绍了PEM文件的格式,包括其内部的ASN.1 DER编码和Base64编码过程。通过示例展示了如何使用openssl工具以及Python脚本进行PEM文件的解码和编码操作,同时解析了私钥和公钥的内容。内容涵盖了PEM文件的结构、ASN.1格式描述以及私钥内容的解释。
摘要由CSDN通过智能技术生成

    详细的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, 
... } 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值