Python sm4加解密

安装模块gmsslpip install gmssl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import binascii
from gmssl import sm3, sm4

# sm3摘要算法实现
def sm3_digest(data):
if type(data) is str:
byte_array_data = bytearray(data.encode('utf-8'))
elif type(data) is bytes:
byte_array_data = bytearray(data)
elif type(data) is bytearray:
byte_array_data = data
else:
logging.info('sm3 digest input error')
return
return sm3.sm3_hash(byte_array_data)


# SM4加密模块
class SM4:
def __init__(self):
self.crypt_sm4 = sm4.CryptSM4()

@staticmethod
def str_to_hex_str(hex_str):
"""
字符串转hex
:param hex_str: 字符串
:return: hex
"""
hex_data = hex_str.encode('utf-8')
str_bin = binascii.unhexlify(hex_data)
return str_bin.decode('utf-8')

def encrypt_sm4(self, encrypt_key: str, value: str, mode: str="ECB", iv: str=None):
"""
sm4加密
:param encrypt_key: sm4加密key
:param value: 待加密的字符串
:param mode: 模式,CBC or ECB
:param iv: 偏移量(ECB模式没有偏移量)
:return: sm4加密后的十六进制值
"""
crypt_sm4 = self.crypt_sm4
crypt_sm4.set_key(encrypt_key.encode('utf-8'), sm4.SM4_ENCRYPT) # 设置密钥
bytes_data = value.encode('utf-8')
if mode == "ECB":
encrypt_value = crypt_sm4.crypt_ecb(bytes_data)
else:
assert iv, 'CBC mode must set iv'
encrypt_value = crypt_sm4.crypt_cbc(iv.encode('utf-8'), bytes_data)
return encrypt_value.hex()

def decrypt_sm4(self, decrypt_key: str, encrypt_value: str, mode: str="ECB", iv: str=None):
"""
sm4解密
:param decrypt_key:sm4加密key
:param encrypt_value: 待解密的十六进制值
:param mode: 模式,CBC or ECB
:param iv: 偏移量(ECB模式没有偏移量)
:return: 原字符串
"""
crypt_sm4 = self.crypt_sm4
crypt_sm4.set_key(decrypt_key.encode('utf-8'), sm4.SM4_DECRYPT)
if mode == 'ECB':
decrypt_value = crypt_sm4.crypt_ecb(bytes.fromhex(encrypt_value))
else:
assert iv, 'CBC mode must set iv'
decrypt_value = crypt_sm4.crypt_cbc(iv.encode('utf-8'), bytes.fromhex(encrypt_value))
return decrypt_value.decode('utf-8')


if __name__ == '__main__':
app_key = "12345678901234561234567890123456"
strData = "90897h8789thvht"
iv = '1234567891234567'
SM4 = SM4()
print("原字符:", strData)
encData = SM4.encrypt_sm4(app_key, strData, mode='CBC', iv=iv) # 加密后的数据
print("sm4加密结果:", encData)

decData = SM4.decrypt_sm4(app_key, encData, mode='CBC', iv=iv)
print("sm4解密结果:", decData) # 解密后的数据