国密算法sm2:微信小程序sm-crypto 和 python 的gmssl 包互通

邓焱
2023-12-01

国密算法sm2:微信小程序sm-crypto 和 python 的gmssl 包互通

前端是微信小程序,后端用Python,数据交互过程中,使用国密sm2加密。
微信小程序的开发文档中,有提供sm-crypto进行sm2加解密的工具文档见: https://developers.weixin.qq.com/miniprogram/dev/extended/utils/sm-crypto.html
python中,找到一个gmssl进行sm2加解密,文档可以看:https://www.codercto.com/soft/d/15729.html

遇到的问题是,两个不同的包,加密出来的东西不一样。
前端小程序使用sm-crypto 加密后的密文 格式为如下:

56c20a877a6f065a16fd65944486a6ef151149d9a0f07b07c4fc6f7b5f99a651adc93db4681e741185d32d3bf21fcc88fea2e0a8cf33777b668d3b1d17274962d7d230be72584260b865f0f5a0518dbc8d1bc2e0b25f4e33db408c7173039a51f3b23b54d67fd0c17ef08567b0a154fd2de77284b6572f5d9a2bf693e2554d389ca29d3166a6ce8e0dc7730e1b97885814bcd4bae20a26ea855f121bfb255437bcc209ca55963c0eb260a96b1e862b88531422027d712ea02dada0d31d2af3a062ea18905757f037a45ed7adebe5244f9b2acc2cdab9708af8f38052006e510b4093b6892a7f3c57e2553dd49fe566d733

后端python的gmssl包对同一个明文加密后,用同样的密钥对,加密后,密文格式如下:

b’c\xe0=\x85\xc5\x9c\xd6M\x87:{\xe6"\xae\xd7\x97\xec\xfa\xf5\x94\xb3t\x17\x17\x08V\xd4\xa0)\xe5\x9fJ\x96\xf7taG\xaa3E\xbe\xb9*d\xb58k\xebmg]\xdc\x1e\xee\xff\x86,:\xaa1R{%\x19Ip\xcfQzv9\xd5!\xb9\xdc\t\x05K\x171\x91|Q\x13\xc7I\x17\xf2\x9d(\xa5\xd2\xda\xde\xd7_\xb4\xd8\x1f\xab\x91\x1e"l\rz\xac\x11Z\xbeX\x1a4r\xda}2\x91\x97\xb8\xb1g\xa4\xafO\xc2\xb5\x9bs\x9aS\xdc}Vqy\xe5\xf3~\xfd\xe5\xb8\xa0q\xdd\xce\xf5\r&
U\xa4\xb7\xe2\x0e\xb0\xbc\x1a\xc3\x02\x92HD\xb9\xff?U\xba\x10\xdb6\xb1n\xed\x07\x98\xe2P\xbe\x8b\xb4Q\xce#>\xf2\x8f\xce\xf0v\x04(N\xee!\x02\x81c\xbb\xc0\xb6\x98\t\xae\x98R\x1cO \x83\xfc"5\xd7\x0e\xff\xf0u\xb70m\x9b\xc4\xa0\x92i\xdd\xae\xfcH\xa3\xf7\xc2_
.\t\xc3\x9e’

所以互相直接加解密是肯定不可以的。经过研究,在python中如下处理就可以。
已知微信小程序加密的得到密文: ms

    v1 = bytes.fromhex( ms )
    print("v1(字符串转bytes):", v1)
    v2 = sm2_crypt.decrypt(v1)
    print("v2(sm2_crypt.decrypt解密之后,应该也是bytes):", v2)
    v3 = v2.decode()
    print("v3(bytes转字符串):", v3)
    v4 = json.loads(v3)
    print("v4(字符串转对象):", v4)

简单写成一行就是:

data = json.loads(sm2_crypt.decrypt( bytes.fromhex(data["data"])).decode())

这里因为明文是json字符串,所以我在python中,把json字符串转对象也做了 json.loads() 。

这是在python 3.5 以上版本可使用的代码。如果是其他版本的,中间字符串转bytes的部分,代码要进行修改。具体可以查看
【Python】bytes和hex字符串之间的相互转换。https://www.cnblogs.com/japhasiac/p/7739846.html

  • 最后小小的提醒一下:加密的时候,要使用接受方的公钥进行加密;解密的时候,要使用自己私钥进行解密。
 类似资料: