4. 公私钥对(RSA,SM2)格式 以及存储

发布时间 2023-06-08 23:43:15作者: Zzangg

公私钥对(RSA,SM2)格式 以及存储

目录


私钥存储

  • 私钥保存形式主要包括,文件形式、密码设备形式和软件系统形式。
  • 当采用文件形式保存私钥时,私钥的安全性通常采用口令进行保护,同时基于口令可对私钥文件迹行加密存储。当系统侧用私钥进行签名或解密时,需要将该私钥文件读入内存或密码模块中进行密码运算。为保护私钥的安全性,通常使用口令对私钥文件进行加密保护。
  • 当采用密码设备形式保存私钥时,密码设备可提供安全机制保护私钥存储的安全性和私钥访问的安全性。

RSA

p126、p152、p222

  • PKCS#1:RSA密码标准

一 格式

  • RSA公钥参数格式的ANS.1描述

  • RSA私钥参数的ANS.1描述

  • PKCS #8 格式下私钥的信息的ASN.1描述

二 存储

1. 使用OpenSSL生成长度为2048的私钥 : private_pkcs1.pem

openssl genrsa -out private_pkcs1.pem 2048

2. 从私钥中派生RSA的公钥 : public_pkcs1.pem

openssl rsa -in private_pkcs1.pem -out public_pkcs1.pem -pubout -RSAPublicKey_out


  • .pem格式

3. 将公钥转换成DER格式

openssl rsa -in private_pkcs1.pem -out public_pkcs1.der -pubout -RSAPublicKey_out -outform DER


DER格式是ASN.1标准化编码规则的一种。这里可以看见DER格式的公钥显示出来的是一堆乱码。我们使用ASN1view查看一下他的内容

结果

这里可以看见,生成的公钥完全符合PKCS #1定义下的ASN.1描述
它的结构是这样的

  • 30 82 01 0A
  • 02 82 01 01
    • 00 bb 98 88 c7 26 e8 0d fd 13 6b 42 7b 17 6f 1e d6 9c bc 7b 93 68 eb 59 b3 ea 44 17 09 61 ba 18 f7 61 d9 b7 c8 fb 9d 4d 2a 01 4d 2b 37 50 06 d4 d1 b6 9c 1f 4b 14 6f 93 0d a1 9d 7c c6 e3 fe d9 af 5c 5a db 10 1f 3e 59 c5 89 cb 55 70 3c 02 1b a7 cb d0 33 71 58 8a 10 10 0b 31 67 76 8f 0b 74 1c d0 8b 37 09 78 a9 87 8a ee 3a 82 80 c0 63 95 19 80 14 bf bb 3e 0b fa 3c e8 d1 dd 34 fb b5 ea 93 53 8c 1e fc 96 82 01 6d ec 89 c5 43 0e f6 17 ad e9 2d 7a fe e2 05 13 eb 39 5f f7 b0 d9 fa dd 4f c9 f1 45 8b 0e d7 ef 5a 1d 7f 67 96 14 07 f9 6e 9d 2e 2f d2 82 11 15 e5 41 b0 d7 3d c0 9d f9 69 17 f9 9d 24 d1 09 9e 95 1c db d1 22 27 18 45 fe 30 c6 fb 2f 3f 83 5e 5f c1 87 f1 86 19 d7 e4 db d1 a0 00 b8 85 f4 77 7e cc 2d 4e b8 4c d4 7a 1f 68 2e e5 fb a1 39 40 6f 6a c8 68 67 13 15 ab 3d
  • 02 03
    • 10 00 01

DER编码分析

  • RSAPublicKey为SEQUENCE结构类型,编码规则为DER定长模式。对于标识串,采用低标识编码方式,只需要一个字节。SEQUENCE的tag为0x10;class选择universal,则第7、8位位0,SEQUENCE为结构类型,则位6位1。因此标识符为0x30。

  • modulus和publicExponent都是INTRGER,所以标识都为0x02。

  • 长度计算,按照下图可知。RSAPublicKey的长度为0x010A,modulus的长度为0x0101,publicExponent的长度为0x03

使用OpenSSL查看密钥的n、e、d

openssl rsa -in private_pkcs1.pem -text -noout

结果如何下

跟通过ASN1view得到的结果完全完全一致

4. 私钥的ASN.1结果

使用ASN1view查看私钥


与标准结构不同的是,asn1view中只显示了9个INTEGER。经过比对私钥中缺少的是标准中的最后一项。并且标准中的version,在私钥中被定义成了INTEGER。

私钥描述

  • version

    类型INTEGER 02 
    长度 01 
    内容 00
    
  • modulus

    类型INTEGER 02 
    长度 82 01 01 
    内容 00 bb 98 88 c7 26 e8 0d fd 13 6b 42 7b 17 6f 1e d6 9c bc 7b 93 68 eb 59 b3 ea 44 17 09 61 ba 18 f7 61 d9 b7 c8 fb 9d 4d 2a 01 4d 2b 37 50 06 d4 d1 b6 9c 1f 4b 14 6f 93 0d a1 9d 7c c6 e3 fe d9 af 5c 5a db 10 1f 3e 59 c5 89 cb 55 70 3c 02 1b a7 cb d0 33 71 58 8a 10 10 0b 31 67 76 8f 0b 74 1c d0 8b 37 09 78 a9 87 8a ee 3a 82 80 c0 63 95 19 80 14 bf bb 3e 0b fa 3c e8 d1 dd 34 fb b5 ea 93 53 8c 1e fc 96 82 01 6d ec 89 c5 43 0e f6 17 ad e9 2d 7a fe e2 05 13 eb 39 5f f7 b0 d9 fa dd 4f c9 f1 45 8b 0e d7 ef 5a 1d 7f 67 96 14 07 f9 6e 9d 2e 2f d2 82 11 15 e5 41 b0 d7 3d c0 9d f9 69 17 f9 9d 24 d1 09 9e 95 1c db d1 22 27 18 45 fe 30 c6 fb 2f 3f 83 5e 5f c1 87 f1 86 19 d7 e4 db d1 a0 00 b8 85 f4 77 7e cc 2d 4e b8 4c d4 7a 1f 68 2e e5 fb a1 39 40 6f 6a c8 68 67 13 15 ab 3d
    
  • publicExponent

    类型 INTEGER 02
    长度 03
    内容 01 00 01
    
  • privateExponent

    类型 INTEGER 02
    长度 82 10 00
    内容 50 7e a6 0a 16 56 b2 51 ea 78 36 c1 8c 8f a0 c2 e3 e4 38 7e 4b 21 d9 8e ca b1 c6 d4 be bb 54 a5 29 b6 7b 16 e1 68 60 c8 ea 60 0b 70 23 85 9a e2 15 a2 2e 07 50 50 83 df f0 7e 1c 21 57 89 6e 2c c1 cb 36 7e 57 79 b0 99 83 83 dd 38 58 77 6b 18 77 ea f1 77 ec 4e e9 8f 88 cd fd 20 31 46 ef de c1 59 4b 17 64 50 12 19 fa 18 df 10 91 fc e8 e8 55 3e 11 fb 2d 27 84 8b 88 37 2c dc e4 38 ed da e6 08 70 b8 81 d7 ca e3 05 8e 57 93 27 d6 40 f1 70 d6 de 0c ca ab 7b ac e3 4a 7d 1d 5e b7 0d 65 18 f7 d6 6c 09 3b c0 ed ef 51 ff 28 56 4e 2c 23 be 42 62 64 69 e9 cd f4 52 d3 3d 83 91 33 e3 12 47 1b 2c c0 10 57 36 8b 23 ec 1c f6 6c ae 06 f5 e3 b0 2b 9f f7 73 7e 1f 5b 06 b2 13 56 ae 52 57 1f 22 59 85 5a 33 9f 9a 8c 47 af 9e de 69 83 34 98 c9 1e ca c7 f1 56 6f 62 e8 7f 79 e9 d2 e6 e1
    
  • prime1(p)

    类型 INTEGER 02
    长度 81 81
    内容 00 f8 a0 64 59 36 3e cb f4 ce c8 2f d4 a4 7a 8d 38 aa 3a 3d 08 6c a8 77 63 85 63 e0 47 dc 74 8e d5 f0 dc a2 19 c0 ca bf 08 15 a6 4d a9 e9 16 e9 7c 06 e1 89 5a 3b c4 e9 ce a0 2d 97 92 32 68 8b e8 8c 04 a7 cc c7 39 9c 4b f0 1c ca 77 0b f6 e3 e5 8d 4e 65 0e 47 3e 90 a0 c6 d2 89 ae 2d 19 52 e6 24 51 09 33 31 43 c9 8b be 5f f5 55 f5 e4 b9 7f 01 68 4c bd 3c eb 3d 75 d0 ff 30 46 94 2e 9b a5
    
  • prime2(q)

    类型 INTEGER 02
    长度 81 81
    内容 00 c1 28 c9 e0 c1 83 3e d7 a2 4f 26 bc b3 d3 6d 9e ee d1 75 bb e5 e7 f2 5d 20 50 2a f7 3b fd 37 37 12 03 bd 1f f0 d7 af 97 26 c1 4f 36 23 82 2f bf 38 af d1 6c 0b b9 39 75 d6 66 24 45 32 b9 2b dd 41 5b c8 ae 0c 2a f6 95 a8 86 3f 9b 21 ef 8b 71 f7 28 bc 94 af 14 d7 55 59 91 19 92 34 02 84 c3 bf bd 21 b5 90 53 d7 f5 e9 d9 a8 73 c5 c4 b4 94 e5 0b 4c 2e ef bb ad a1 cd a4 04 ce 81 b7 9d b9
    
  • exponent1

    类型 INTEGER 02
    长度 81 80
    内容 40 0f 63 8b b0 f4 61 2c c4 92 c3 f0 30 28 fb 76 1c 36 41 3f 88 6f a7 c3 56 bd 33 2e 90 d8 df 6c b4 50 c4 db 89 d7 33 7d 6b c6 9b c0 29 b4 a3 98 37 55 a9 44 3c 9e 31 f7 f1 41 8e 0a 37 3e c4 bd b8 46 02 ce 3a 8e d7 7c a1 73 69 9f 5e cf d0 4c 77 2a 39 d3 81 fb d6 db f6 1e 8d 26 f9 ab ca b6 4d a9 2b 8b ab 27 e2 28 45 77 08 09 8b ff d0 e3 ae 83 27 32 a3 1d a1 8a 57 bd 48 bd 06 b5 33 99
    
  • exponent2

    类型 INTEGER 02
    长度 81 81
    内容 00 ae 9c 9c c2 5c ac b4 66 62 07 83 51 1a 8e 8a 8e 1d fd a3 9c 94 1c b5 6f 92 02 66 94 d0 d9 fa cc 01 b0 f7 8a a4 41 96 2d e1 8e e6 78 5e 69 15 98 9b 39 f4 ea e3 3e 31 bf 60 6d 3d 64 80 91 fc 21 2b 30 39 9d 7c ca 69 d6 a8 5d 93 aa 3d 67 3a 7b 6f 9e 97 bb 20 fa 8a 1e 51 b5 65 94 51 07 e5 d4 be c3 ce 71 3f 63 4b da b5 e7 58 ec 2f 5f be 8e ca ef 07 93 76 8c 06 4e 3a 83 87 04 d7 26 91 a1
    
  • coefficient

    类型 INTEGER 02
    长度 81 81
    内容 00 d5 a5 84 48 e8 69 89 d7 58 14 ea 34 7f 57 59 50 1c 30 5c fc fb f8 8c 4b dd 1e ec 81 a4 63 ff 17 2e cb 18 84 4f 40 75 ad e4 ff 50 a5 e8 5c cc 65 c2 b4 74 60 ba 26 e5 3f 98 16 fe 30 0c c5 1f 8c c4 a4 7c 80 be e6 8f cc ff 53 52 05 c1 f3 22 ed 17 7f 08 64 3b a9 28 8b ae df 42 0b 58 5d 5d 75 18 33 dd 71 15 71 25 52 84 49 a3 a9 4e 1e 5f 05 5e 9e c4 3f 9c 96 b9 af a8 99 83 80 3f 58 57 f7 42
    

5. PKCS #8的RSA私钥存储

PKCS #8规定私钥单独以文件形式存储的格式

  • 私钥密文格式使用ASN.1描述

    encryptedAlgorithm是密码算法标识,用于加密私钥。密钥通常为对称密钥,通常由口令产生。encryptedData保存加密后的私钥。私钥明文首先使用PrivateKeyInfo形式编码,由encryptedAlgorithm所标识的对称密码算法加密后保存到encryptedData中。
  • PrivateKeyInfo的ASN.1描述

RSA密钥的PKCS #8存储的ASN.1的描述

  • 将pkcs #1格式的RSA私钥转换成pkcs #8

openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in private_pkcs1.pem -out private_pkcs8.pem ,不对私钥进行加密

  • 使用ASN1view查看private_pkcs8.pem

encryptedData

在ASN.1view中被选中的浅蓝色区域就是私钥明文的一部分。

encryptedAlgorithm

version

缺省置为0

  • 尝试生成被加密的pkcs #8格式私钥

openssl pkcs8 -topk8 -inform PEM -outform PEM -passout pass:20201326 -in private_pkcs1.pem -out private_pkcs8_2.pem,加密密码:20201326

ASN1view查看

与前面未加密的相比在第二部分多了很多内容。

第一部分

结构

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

转换给定具体数值后,该部分的ASN.1描述结构如下:


  • 30 57 -- AlgorithmIdentifier 结构整体长度
    • 06 09 2a 86 48 86 f7 0d 01 05 0d -- Object Identifier (OID) 1.2.840.113549.1.5.13 (pbkdf2WithHMACSHA1)
    • 30 4a --参数部分讲述
      • 30 29 -- AlgorithmParameters 结构长度
        • 06 09 2a 86 48 86 f7 0d 01 05 0c
        • 30 1c -- PBKDF2-params 结构长度
          • 04 08 -- salt 长度
            • b5 82 a5 ba 16 d4 1a 3b -- salt
          • 02 02 -- iterations 长度
            • 08 00 -- iterationCount = 2048
          • 30 0c -- prf - AlgorithmIdentifier 结构长度
            • 06 08 -- PBKDF2-prf OBJECT IDENTIFIER 长度
              • 2a 86 48 86 f7 0d 02 09 05 00 - OID=1.2.840.113549.2.9 (HMAC-SHA256)

其中,algorithm字段表示该私钥的加密算法,由OID确定,这里的OID为1.2.840.113549.1.5.13,表示使用PBKDF2进行密钥派生。parameters字段是可选字段,表示加密算法所需的参数,这里使用了PBKDF2的参数。parameters字段的具体结构包含了salt、iterationCount和PRF(Pseudo-Random Function)三部分,表示密钥派生中的盐值、迭代次数和伪随机函数。salt是一个8个字节长的随机数值;iterationCount表示密钥派生循环次数,这里的值为2048;PRF表示伪随机函数,这里采用HMAC-SHA256。

encryptedData

这里明显的发现内容被加密了,与明文不同



SM2

p128、p152、

格式

《SM2密码算法使用规范》规定了SM2的算法和公/私钥格式,在国家标准中能够查到

  • SM2公钥格式用ASN.1描述
  • SM2私钥格式用ASN.1描述

存储

生成一个长为2048的私钥

openssl ecparam -genkey -name SM2 -out private_sm2_key.pem


派生公钥

openssl ec -in private_sm2_key.pem -pubout -out public_sm2_key.pem

将公私钥转换成DER格式

公钥:openssl ec -in public_sm2_key.pem -pubin -outform der -out public_sm2_key.der

私钥:openssl ec -in private_sm2_key.pem -outform der -out private_sm2_key.der

公钥


第一个OBJECT IDENTIFIRE:公钥参数
第二个OBJECT IDENTIFIRE:算法标识符
BIT STRING:SM2公钥坐标

私钥

INTEGER :私钥的版本号
OCTET STRING:私钥参数集
Context[0]:算法标识符
Context[1]:私钥的值

将SM2密钥存储格式转为PKCS #8

pkcs #8对密钥的描述



公钥

openssl pkey -inform PEM -in private_sm2_pkcs8.pem -pubout -outform PEM -out public_sm2_pkcs8.pem



私钥

openssl pkcs8 -topk8 -inform PEM -in private_sm2_key.pem -outform PEM -nocrypt -out private_sm2_pkcs8.pem



  • 30 81 87 -- PrivateKeyInfo 结构整体长度
    • 02 01 00 -- version,值为 0
    • 30 13 -- AlgorithmIdentifier 结构长度
      • 06 07 2a 86 48 ce 3d 02 01 -- Object Identifier (OID) 1.2.840.10045.2.1 (ECDSA with SHA-1)
      • 06 08 2a 81 1c cf 55 01 82 2d -- Object Identifier (OID) 1.2.156.10197.1.2.2 (SM2 encryption and signature algorithm)
    • 04 6d -- 私钥长度,值为 109
      • 30 6b -- ECPrivateKey 结构长度
        • 02 01 01 -- 私钥版本号,值为 1
        • 04 20 -- 私钥 (d) 长度,值为 32
          • 53 11 10 26 01 d9 77 49 9e 85 8d ce 9d a3 47 00 a3 a4 2b d1 b1 99 0d 76 dd 1e ab 8f e2 86 ef 3c
          • a1 44 03 42
        • a0 3c -- 曲线参数部分
          • 30 3a -- ECParameters 结构长度
            • 06 07 2a 86 48 ce 3d 02 01 -- Object Identifier (OID) 1.2.840.10045.3.1.7 (SM2 curve)
            • 02 01 00 -- 椭圆曲线版本号,值为 0
            • 30 2c -- 椭圆曲线参数部分长度
              • 06 08 2a 81 1c cf 55 01 82 2d -- Object Identifier (OID) 1.2.156.10197.1.2.2 (SM2 encryption and signature algorithm)
              • 02 20 -- 曲线参数 (a) 长度,值为 32
                • c7 53 01 0c 62 aa 95 68 19 c5 bf 19 d7 91 07 d7 bd 6e d5 36 44 88 a7 4c 1b 16 aa 2e 8a f8 5d fe
              • 02 20 -- 曲线参数 (b) 长度,值为 32
                • 84 71 46 57 c0 c7 de aa 43 7e 58 5e ba e5 02 c8 57 70 62 06 03 c5 42 72 9c 18 86 7b 1e be 26 eb

asn1view的结果对比标准来看,是满足pkcs#8的标准的。这里生成的pkcs#8的公/私钥没有经过加密。如果想要尝试加密可以参考PKCS #8的RSA私钥存储中的对RSA的加密存储。



参考