python wrapper of GmSSL
Project description
gmssl_pyx
python wrapper of GmSSL
使用的版本是 GmSSL-3.1.0
支持 Python 3.7, 3.8, 3.9, 3.10
安装
pip install gmssl-pyx
SM2
加密和解密
from gmssl_pyx import sm2_key_generate, sm2_encrypt, sm2_decrypt
# 生成 SM2 公私钥
public_key, private_key = sm2_key_generate()
# 加密
plaintext = b"hello world"
ciphertext = sm2_encrypt(public_key, plaintext)
print("ciphertext", ciphertext)
# 解密
plaintext = sm2_decrypt(private_key, ciphertext)
print("plaintext", plaintext)
签名和验签
from gmssl_pyx import sm2_key_generate, sm2_sign, sm2_verify
# 生成 SM2 公私钥
public_key, private_key = sm2_key_generate()
# 没有 signer_id 和 SM3 杂凑值 z
# 签名
message = b"hello world"
signature = sm2_sign(private_key, public_key, message, signer_id=None)
print("signature", signature)
# 验证签名
verify = sm2_verify(private_key, public_key, message, signature, signer_id=None)
print("verify", verify)
# 默认 signer_id 和 SM3 杂凑值 z
signature = sm2_sign(private_key, public_key, message)
print("signature", signature)
# 验证签名
verify = sm2_verify(private_key, public_key, message, signature)
print("verify", verify)
# 自定义 signer_id 和 SM3 杂凑值 z
signer_id = b"signer_id"
signature = sm2_sign(private_key, public_key, message, signer_id=signer_id)
print("signature", signature)
# 验证签名
verify = sm2_verify(private_key, public_key, message, signature, signer_id=signer_id)
print("verify", verify)
ASN.1 DER 编码
加密和签名的结果都是 ASN.1 DER 编码,如果要得到原始的密文和签名,可以参考下面的例子
需要安装 pycryptodomex 库
pip install pycryptodomex
from Cryptodome.Util.asn1 import DerSequence, DerOctetString, DerInteger
from gmssl_pyx import sm2_key_generate, sm2_encrypt, sm2_decrypt
# 生成 SM2 公私钥
public_key, private_key = sm2_key_generate()
# 加密
plaintext = b"hello world"
ciphertext = sm2_encrypt(public_key, plaintext)
print("ciphertext", ciphertext)
seq_der = DerSequence()
decoded_ciphertext = seq_der.decode(ciphertext)
# ASN.1 DER 解码
# c1: point(x, y) 64bytes
# c2: ciphertext len(data)
# c3: hash 32bytes
# der order: c1x c1y hash ciphertext
c1x = decoded_ciphertext[0]
c1y = decoded_ciphertext[1]
c3 = DerOctetString().decode(decoded_ciphertext[2]).payload
c2 = DerOctetString().decode(decoded_ciphertext[3]).payload
# 模式为 C1C3C2
raw_ciphertext = c1x.to_bytes(32, "big") + c1y.to_bytes(32, "big") + c3 + c2
# 如果需要解密原始密文,需要先进行 ASN.1 DER 编码
seq_der = DerSequence()
c1x = raw_ciphertext[:32]
x = DerInteger(int.from_bytes(c1x, byteorder='big'))
seq_der.append(x)
c1y = raw_ciphertext[32:64]
y = DerInteger(int.from_bytes(c1y, byteorder='big'))
seq_der.append(y)
c3 = raw_ciphertext[64:64 + 32]
seq_der.append(DerOctetString(c3))
c2 = raw_ciphertext[64 +32:]
seq_der.append(DerOctetString(c2))
ciphertext = seq_der.encode()
plaintext = sm2_decrypt(private_key, ciphertext)
print("plaintext", plaintext)
# 签名
signature = sm2_sign(private_key, public_key, message)
seq_der = DerSequence()
decoded_sign = seq_der.decode(signature)
# ASN.1 DER 解码,两个 32 字节的整数
r = decoded_sign[0]
s = decoded_sign[1]
print('r', r)
print('s', s)
raw_signature = '%064x%064x' % (r, s)
# 验证原始签名同样需要先进行 ASN.1 DER 编码
r = int(raw_signature[:64], base=16)
s = int(raw_signature[64:], base=16)
seq_der = DerSequence()
seq_der.append(DerInteger(r))
seq_der.append(DerInteger(s))
signature = seq_der.encode()
verify = sm2_verify(private_key, public_key, message, signature)
print('verify', verify)
公私钥的一些补充说明
公钥长度为 64 字节,是两个 32 字节的整数 x y 拼接而成。
如果公钥长度为 65 字节,那么第一个字节为 '\x04' ,表示后面的 64 字节就是公钥。
如果公钥长度为 33 字节,那么第一个字节为 '\x02' 或者 '\x03' , 这是一种压缩格式,后面的 32 字节为整数 x , y 可以根据 x 计算出来。
私钥长度为 32 字节,没有其他变化。
from gmssl_pyx import sm2_key_generate, normalize_sm2_public_key
raw_public_key, _ = sm2_key_generate()
k1 = normalize_sm2_public_key(raw_public_key)
assert k1 == raw_public_key
k1 = normalize_sm2_public_key(b'\x04' + raw_public_key)
assert k1 == raw_public_key
# 压缩版公钥
y = int.from_bytes(raw_public_key[32:], byteorder='big')
if y % 2 == 0:
# y 是偶数
compressed_public_key = b'\x02' +raw_public_key[:32]
else:
compressed_public_key = b'\x03' + raw_public_key[:32]
k1 = normalize_sm2_public_key(compressed_public_key)
assert k1 == raw_public_key
SM3
hash 计算
from gmssl_pyx import sm3_hash
message = b'hello world'
signature = sm3_hash(message)
print('message', message)
print('signature', signature.hex())
hmac 计算
import secrets
from gmssl_pyx import sm3_hmac
key = secrets.token_bytes(32)
message = b"sm3_hmac"
hmac_data = sm3_hmac(key, message)
print("message", message)
print("hmac_data", hmac_data)
kdf 计算
import secrets
from gmssl_pyx import sm3_kdf
key = secrets.token_bytes(32)
new_key = sm3_kdf(key, 32)
print('kdf new_key', new_key)
SM4
CBC 模式加密和解密
import secrets
from gmssl_pyx import (
sm4_cbc_padding_encrypt,
sm4_cbc_padding_decrypt,
SM4_KEY_SIZE,
SM4_BLOCK_SIZE,
)
key = secrets.token_bytes(SM4_KEY_SIZE)
iv = secrets.token_bytes(SM4_BLOCK_SIZE)
plaintext = b"hello world"
# 加密
ciphertext = sm4_cbc_padding_encrypt(key, iv, plaintext)
print("ciphertext", ciphertext.hex())
# 解密
decrypted = sm4_cbc_padding_decrypt(key, iv, ciphertext)
print("decrypted", decrypted)
CTR 模式加密和解密
import secrets
from gmssl_pyx import (
sm4_ctr_encrypt,
sm4_ctr_decrypt,
SM4_KEY_SIZE,
SM4_BLOCK_SIZE,
)
key = secrets.token_bytes(SM4_KEY_SIZE)
ctr = secrets.token_bytes(SM4_BLOCK_SIZE)
plaintext = b"hello world"
# 加密
ciphertext = sm4_ctr_encrypt(key, ctr, plaintext)
print("ciphertext", ciphertext.hex())
# 解密
decrypted = sm4_ctr_decrypt(key, ctr, ciphertext)
print("decrypted", decrypted)
GCM 模式加密和解密
import secrets
from gmssl_pyx import sm4_gcm_encrypt, sm4_gcm_decrypt, SM4_KEY_SIZE, SM4_BLOCK_SIZE
plaintext = b'hello world'
key = secrets.token_bytes(SM4_KEY_SIZE)
iv = secrets.token_bytes(SM4_BLOCK_SIZE)
aad = secrets.token_bytes(16)
# 加密
ciphertext, tag = sm4_gcm_encrypt(key, iv, aad, plaintext=plaintext)
print('ciphertext', ciphertext)
# 解密
plaintext = sm4_gcm_decrypt(key, iv=iv, aad=aad, ciphertext=ciphertext, tag=tag)
print('plaintext', plaintext)
其他
如果要查看所有可用的 API ,可以看 gmsslext.pyi 文件。
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
gmssl_pyx-1.1.0.tar.gz
(22.8 kB
view hashes)
Built Distributions
Close
Hashes for gmssl_pyx-1.1.0-cp310-cp310-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | c1f026dee840dc954d00db150a5856fcadc72d1554d938ff34d21daa9831fa39 |
|
MD5 | e66b5fae2c8353e16babd183b27e4eb2 |
|
BLAKE2b-256 | f59fbdcbd740f5ac5d4d56f5039b78e93a8ac3af7d96e3512bd16f5f99486e8c |
Close
Hashes for gmssl_pyx-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 64e47de3dd2db1ae62121a4e4914d45dd1cb72ab461109e68d64d1c93d2ca6f5 |
|
MD5 | 8f4ecfbe4e67c2389c6c4d8d3d999bd6 |
|
BLAKE2b-256 | 0596412b0e8f84e0b11d74f1560e684babd5f72afcb55daffb1b40a354d31ed0 |
Close
Hashes for gmssl_pyx-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | cff11f38891440557c01209b747a4a1dbcb63e634cc1c0396fc164a9e19b0992 |
|
MD5 | 9554fa78ee2a2f92869ffa633ab22cc5 |
|
BLAKE2b-256 | 9bfe26b5ea197996198d2f8add2d58438dc40cc85b7dc108e4ec628cd8b49456 |
Close
Hashes for gmssl_pyx-1.1.0-cp39-cp39-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b3cc3aa9fa3432b2bc56fb6a07e8a79cee2efa85251772bdaca6cb2eabc7d887 |
|
MD5 | a7cab29f81df4485fd0f7c81041731ad |
|
BLAKE2b-256 | 5d2c265ce6968653634287329f009cf7e894c252e42b47460da1db186f4355eb |
Close
Hashes for gmssl_pyx-1.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1f866eddde1287a2d54035689352f9d23c5341f1d070a88a707f3b034883a179 |
|
MD5 | 90777d70a373a5385835fd48b62b8726 |
|
BLAKE2b-256 | 94ba3efdfef9e76bef032a3d9844ae6861b004c4a5bd48ec0faf22283865b0e2 |
Close
Hashes for gmssl_pyx-1.1.0-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5712151cb6db7af2cc021495baadfc3a246a56340ec79318d88ab5c7b2cbd0a3 |
|
MD5 | 521f4d40a36a54e5e538f98bb06b6051 |
|
BLAKE2b-256 | c8394466d3e10c8a4183315d4f151d01a20ddeee4ff2b3bfcdd6c60a93467c61 |
Close
Hashes for gmssl_pyx-1.1.0-cp38-cp38-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d5752dc18a8aac427de586a588996ce7ff45f4675159cd96b528e5ce2ebff9cc |
|
MD5 | 9b396e5f00e5f2203f57e8bddc56ec31 |
|
BLAKE2b-256 | 1e27611f761619aa148a9bcf4b9660cdd5fbc37d6811b96a83ace99662b3aa28 |
Close
Hashes for gmssl_pyx-1.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | bbe183918fec450c77c9f854d023cb6cef844e4d14cd2329f9212a3c5e73bfdc |
|
MD5 | c7ac7d26663539f336d53bdb5a50768b |
|
BLAKE2b-256 | 6e393a7b8a06a116bf8bba552b2dc507dc67816adc49a6d0dc777adf2b0f151a |
Close
Hashes for gmssl_pyx-1.1.0-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 623d59d7bcb91d2e34f73ea2f1471526f860e378eb34798131076abebdb6e21c |
|
MD5 | d1a74fd9d1f0a644b40c981dc3b8e89c |
|
BLAKE2b-256 | ce3516137394516b7ec294835bf26423f20868aae7cb340b9df96357e3ad3d79 |
Close
Hashes for gmssl_pyx-1.1.0-cp37-cp37m-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6fced4ecf602ede8496b2c7a0cb534f3a493c3d0143075a4e2680e8e250fa00b |
|
MD5 | b3b6cfd1441e64f2c365f8188db9ca06 |
|
BLAKE2b-256 | 6ade7f884defc3338cc504bdbdbc73d19991e3531f7ad2597be5a6c27b22f906 |
Close
Hashes for gmssl_pyx-1.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2df994127f37d5c10b9271193f5f23324f322358372228d413b14b2e8595fd8c |
|
MD5 | 241c45087513724f396c2f53b2338fef |
|
BLAKE2b-256 | 4a9a747ac9224bfcf08555a695b63818e414d24e27eac43a8fdf150cc818e0b3 |
Close
Hashes for gmssl_pyx-1.1.0-cp37-cp37m-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | e07b93a19c82a414c053432d506d936321a382df2ac54f3a82a7c10fba65e806 |
|
MD5 | 207523ee8e6fe401f28afa1944aab00c |
|
BLAKE2b-256 | 034c638ba318c6747fd57d675c763eb2b872e332b03cc8cba35aaac77aca08e5 |