sm2格式數字信封加解密詳解

sm2格式數字信封

0、參考鏈接

密碼行業標準化技術委員會
	http://www.gmbz.org.cn/main/bzlb.html
SM2密碼算法使用規範
	http://www.gmbz.org.cn/main/viewfile/2018011001400692565.html
SM2密碼算法應用分析
	https://blog.csdn.net/arlaichin/article/details/23708155?utm_source=itdadao&utm_medium=referral
技術科普 | 國密算法在Ultrain區塊鏈中的運用 
	https://blog.csdn.net/Tramp_1/article/details/111603396

1、sm2數字信封格式:

有效部分
公鑰:04|X|Y,共65字節
私鑰:整數,共32字節
SM2EnvelopedKey ::= SEQUENCE {
   
   
    symalgid        AlgorithmIdentifier,        -- 對稱算法ID
    symalgkey       SM2Cipher,                  -- 對稱算法密鑰(被簽名證書公鑰加密)
    asympubkey      BIT STRING,                 -- 加密證書公鑰
    asymprvkey      BIT STRING                  -- 加密證書私鑰(被對稱算法加密)
}
typedef struct SM2Cipher_st {
   
   
    ASN1_INTEGER *xCoordinate;                                // x分量(隨機,非公鑰)
    ASN1_INTEGER *yCoordinate;                                // y分量(隨機,非公鑰)
    ASN1_OCTET_STRING *hash;                                  // 雜湊值
    ASN1_OCTET_STRING *cipherText;                            // 密文
} SM2Cipher;
AlgorithmIdentifier ::= SEQUENCE {
   
   
    algorithm       OBJECT IDENTIFIER,
    parameters      ANY DEFINED BY algorithm OPTIONAL
}

區分普通的數字信封格式,見下圖(openssl暫不支持sm2算法的私鑰p7信封格式生成,但是支持sm2算法私鑰的p7解密,生成p7可以在外部使用gmssl命令行生成)
typedef struct pkcs7_enveloped_st {
   
   
    ASN1_INTEGER *version;      /* version 0 */
    STACK_OF(PKCS7_RECIP_INFO) *recipientinfo;
    PKCS7_ENC_CONTENT *enc_data;
} PKCS7_ENVELOPE;
typedef struct pkcs7_recip_info_st {
   
   
    ASN1_INTEGER *version;      /* version 0 */
    PKCS7_ISSUER_AND_SERIAL *issuer_and_serial;
    X509_ALGOR *key_enc_algor;
    ASN1_OCTET_STRING *enc_key;
    X509 *cert;                 /* get the pub-key from this */
    const PKCS7_CTX *ctx;
} PKCS7_RECIP_INFO;
typedef struct pkcs7_enc_content_st {
   
   
    ASN1_OBJECT *content_type;
    X509_ALGOR *algorithm;
    ASN1_OCTET_STRING *enc_data; /* [ 0 ] */
    const EVP_CIPHER *cipher;
    const PKCS7_CTX *ctx;
} PKCS7_ENC_CONTENT;
typedef struct pkcs7_st {
   
   
    /*
     * The following is non NULL if it contains ASN1 encoding of this
     * structure
     */
    unsigned char *asn1;
    long length;
# define PKCS7_S_HEADER  0
# define PKCS7_S_BODY    1
# define PKCS7_S_TAIL    2
    int state;                  /* used during processing */
    int detached;
    ASN1_OBJECT *type;
    /* content as defined by the type */
    /*
     * all encryption/message digests are applied to the 'contents', leaving
     * out the 'type' field.
     */
    union {
   
   
        char *ptr;
        /* NID_pkcs7_data */
        ASN1_OCTET_STRING *data;
        /* NID_pkcs7_signed */
        PKCS7_SIGNED *sign;
        /* NID_pkcs7_enveloped */
        PKCS7_ENVELOPE *enveloped;
        /* NID_pkcs7_signedAndEnveloped */
        PKCS7_SIGN_ENVELOPE *signed_and_enveloped;
        /* NID_pkcs7_digest */
        PKCS7_DIGEST *digest;
        /* NID_pkcs7_encrypted */
        PKCS7_ENCRYPT *encrypted;
        /* Anything else */
        ASN1_TYPE *other;
    } d;
    PKCS7_CTX ctx;
} PKCS7;

在這裏插入圖片描述

2、代碼中sm2數字信封加密解密步驟

加密(將加密私鑰明文轉換爲sm2信封格式密文)
1、將加密證書私鑰轉換爲der格式(二進制)
2、設置對稱算法ID,公鑰有效數據部分,私鑰有效數據部分
	對稱算法ID默認爲0x2a, 0x81, 0x1c, 0xcf, 0x55, 0x01, 0x68, 0x01(即sm4_ecb,1.2.156.10197.1.104.1)
	公鑰數據前綴爲0xa1, 0x44, 0x03, 0x42, 0x00,截取65字節明文
	私鑰數據前綴爲0x02, 0x01, 0x01, 0x04, 0x20,截取32字節明文
3、創建對稱密鑰,加密私鑰有效數據部分
	使用sm4_ecb算法和創建的128位隨機密鑰,加密私鑰32字節得到32字節密文
4、使用簽名公鑰加密對稱密鑰,密文轉換爲二進制
	使用sm2算法加密128位對稱密鑰,得到對稱密鑰密文(此處我使用了openssl已實現的sm2算法加密,因此不需要按照國標文檔裏深入底層計算預處理結果Za)
5、將對稱算法ID,對稱密鑰密文,公鑰,私鑰密文轉換爲信封格式數據(此處可以參考openssl內部代碼實現結構體和i2d格式轉換)
6、將der二進制信封轉換爲pem格式(base64),輸出
解密(將sm2數字信封格式轉換爲加密私鑰)
1、p7(pem格式)轉二進制
2、解析二進制,得到對稱算法ID,對稱算法密鑰密文,加密證書公鑰,加密證書私鑰密文二進制
3、對稱算法ID轉具體算法名稱
	二進制字符串ID轉換爲OID(1.2.156.10197.1.104.1)進行匹配
4、簽名私鑰解密,得到對稱算法密鑰
	使用sm2算法解密對稱密鑰密文,得到對稱密鑰明文
5、對稱算法解密,得到加密私鑰有效數據,32字節
	使用sm4_ecb算法和對稱密鑰明文,解密私鑰32字節密文得到32字節明文
6、拼接公鑰,私鑰得到完整加密私鑰der二進制格式,有兩種方式(此處拼接方法是我自己創造的,有什麼其他好方法歡迎共享)
(1)"30770201010420"+32字節私鑰+"a00a06082a811ccf5501822da144034200"+65字節公鑰	(2)"308187020100301306072A8648CE3D020106082A811CCF5501822D046D306B0201010420"+32字節私鑰+"A144034200"+65字節公鑰
7、轉換der得到pem格式文件

3、sm2數字信封格式詳解

p7pem格式(base64)
MIHtMAkGByqBHM9VAWgweQIgMtHF6qRZOKJxnT5MYSv4eK/LjJHmp7b/p7AaP6cqigkCIQCFpr2MmakaMxVH1u+Yzxf+oJSFETwiZacB4j3NohlbHwQgO50Hic8tDYBLedIbuqsS2lXvPDYtyuLUrQKyGRI1Y9gEEA5lnd3Yxujfedxk6Cam9ygDQgAEnrxloYKoCRYc3Lh96OYupmT7V7X/BBgdcfCMQnsB7nQhD6FVwgKoN0JMwMqHXGg6l891FCfuTh5N51YqOAqBwwMhAHiB9UgemN+Xz39qsdMeVl4SKdmHHkPkKmNOBJjoqHor

p7二進制
3081ED300906072A811CCF5501683079022032D1C5EAA45938A2719D3E4C612BF878AFCB8C91E6A7B6FFA7B01A3FA72A8A0902210085A6BD8C99A91A331547D6EF98CF17FEA09485113C2265A701E23DCDA2195B1F04203B9D0789CF2D0D804B79D21BBAAB12DA55EF3C362DCAE2D4AD02B219123563D804100E659DDDD8C6E8DF79DC64E826A6F728034200049EBC65A182A809161CDCB87DE8E62EA664FB57B5FF04181D71F08C427B01EE74210FA155C202A837424CC0CA875C683A97CF751427EE4E1E4DE7562A380A81C30321007881F5481E98DF97CF7F6AB1D31E565E1229D9871E43E42A634E0498E8A87A2B

主要包含(1)(2)(3)(4)

3081ed30090607
(1)對稱算法ID:sms4		    			  			2a811ccf550168
(2)對稱算法密鑰密文(sm2加密):								3079022032d1c5eaa45938a2719d3e4c612bf878afcb8c91e6a7b6ffa7b01a3fa72a8a0902210085a6bd8c99a91a331547d6ef98cf17fea09485113c2265a701e23dcda2195b1f04203b9d0789cf2d0d804b79d21bbaab12da55ef3c362dcae2d4ad02b219123563d804100e659dddd8c6e8df79dc64e826a6f728

拆解後:
30790220
x:32d1c5eaa45938a2719d3e4c612bf878afcb8c91e6a7b6ffa7b01a3fa72a8a09
022100
y:85a6bd8c99a91a331547d6ef98cf17fea09485113c2265a701e23dcda2195b1f
0420
m:3b9d0789cf2d0d804b79d21bbaab12da55ef3c362dcae2d4ad02b219123563d8
0410
c:0e659dddd8c6e8df79dc64e826a6f728
(c結構密文)
04|x|y|m|c
0432D1C5EAA45938A2719D3E4C612BF878AFCB8C91E6A7B6FFA7B01A3FA72A8A0985A6BD8C99A91A331547D6EF98CF17FEA09485113C2265A701E23DCDA2195B1F3B9D0789CF2D0D804B79D21BBAAB12DA55EF3C362DCAE2D4AD02B219123563D80E659DDDD8C6E8DF79DC64E826A6F728

使用sm2簽名私鑰解密(2)後得到
對稱密鑰明文:EP/+Xo55MBhI3e1GTyghhQ==:10FFFE5E8E79301848DDED464F282185
(3)加密證書公鑰:									  
034200
有效數據明文(65B):049ebc65a182a809161cdcb87de8e62ea664fb57b5ff04181d71f08c427b01ee74210fa155c202a837424cc0ca875c683a97cf751427ee4e1e4de7562a380a81c3
(4)加密證書私鑰(加密):
032100
有效數據密文(32B):7881f5481e98df97cf7f6ab1d31e565e1229d9871e43e42a634e0498e8a87a2b

使用(2)中對稱密鑰解密得到sm2私鑰有效數據明文
cipher.txt.bin:7881f5481e98df97cf7f6ab1d31e565e1229d9871e43e42a634e0498e8a87a2b #需要將十六進制轉換爲二進制文件
openssl enc -d -sm4-ecb -in cipher.txt.bin -K 10FFFE5E8E79301848DDED464F282185 -p -out plain.txt.bin #解密得到明文
加密驗證
plain.txt.bin:71e49d78b44c6fd54331869f343c537c0a736954ae22cd50277ae587a7e6762e #需要將十六進制轉換爲二進制文件
openssl enc -e -sm4-ecb -nopad -in plain.txt.bin  -K 10FFFE5E8E79301848DDED464F282185 -p -out cipher.txt.bin #使用明文加密得到


加密證書公鑰der:
3059301306072a8648ce3d020106082a811ccf5501822d034200
049ebc65a182a809161cdcb87de8e62ea664fb57b5ff04181d71f08c427b01ee74210fa155c202a837424cc0ca875c683a97cf751427ee4e1e4de7562a380a81c3

加密證書私鑰der(格式1):
308187020100301306072A8648CE3D020106082A811CCF5501822D046D306B0201010420
私鑰有效數據  						71E49D78B44C6FD54331869F343C537C0A736954AE22CD50277AE587A7E6762E
									A144034200
公鑰有效數據049EBC65A182A809161CDCB87DE8E62EA664FB57B5FF04181D71F08C427B01EE74210FA155C202A837424CC0CA875C683A97CF751427EE4E1E4DE7562A380A81C3

加密證書私鑰der(格式2):
30770201010420
私鑰有效數據							71e49d78b44c6fd54331869f343c537c0a736954ae22cd50277ae587a7e6762e
a00a06082a811ccf5501822d
									a144034200													
公鑰有效數據					049ebc65a182a809161cdcb87de8e62ea664fb57b5ff04181d71f08c427b01ee74210fa155c202a837424cc0ca875c683a97cf751427ee4e1e4de7562a380a81c3
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章