Python 使用国密有很多第三方库
有gmssl、pycryptodome等
以下是手动实现(参考了网上的代码且做略微修改)
from array import array Tj_rl = array('L', ((0x79cc4519 << j | 0x79cc4519 >> 32 - j) & 0xffffffff for j in range(16))) Tj_rl.extend((0x7a879d8a << (j & 31) | 0x7a879d8a >> (32 - j & 31)) & 0xffffffff for j in range(16, 64)) V0 = array('L', [0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e]) def CF(V, B): W = array('L', B) for j in range(16, 68): X = W[j - 16] ^ W[j - 9] ^ (W[j - 3] << 15 | W[j - 3] >> 17) & 0xffffffff W.append((X ^ (X << 15 | X >> 17) ^ (X << 23 | X >> 9) ^ (W[j - 13] << 7 | W[j - 13] >> 25) ^ W[j - 6]) & 0xffffffff) W_ = array('L', (W[j] ^ W[j + 4] for j in range(64))) A, B, C, D, E, F, G, H = V for j in range(64): A_rl12 = A << 12 | A >> 20 tmp = (A_rl12 + E + Tj_rl[j]) & 0xffffffff SS1 = (tmp << 7 | tmp >> 25) SS2 = SS1 ^ A_rl12 if j & 0x30: # 16 <= j FF, GG = A & B | A & C | B & C, E & F | ~E & G else: FF, GG = A ^ B ^ C, E ^ F ^ G TT1, TT2 = (FF + D + SS2 + W_[j]) & 0xffffffff, (GG + H + SS1 + W[j]) & 0xffffffff C, D, G, H = (B << 9 | B >> 23) & 0xffffffff, C, (F << 19 | F >> 13) & 0xffffffff, G A, B, E, F = TT1, A, (TT2 ^ (TT2 << 9 | TT2 >> 23) ^ (TT2 << 17 | TT2 >> 15)) & 0xffffffff, E return A ^ V[0], B ^ V[1], C ^ V[2], D ^ V[3], E ^ V[4], F ^ V[5], G ^ V[6], H ^ V[7] def digest(data): # 填充 pad_num = 64 - (len(data) + 1 & 0x3f) data += b'\x80' + (len(data) << 3).to_bytes(pad_num if pad_num >= 8 else pad_num + 64, 'big') V, B = V0, array('L', data) B.byteswap() # 迭代压缩 for i in range(0, len(B), 16): V = CF(V, B[i:i + 16]) V = array('L', V) V.byteswap() return V.tobytes()
使用gmssl库进行比对算出来的结果
from gmssl import sm3, func from util.gm_util import digest def test_sm3(): data = "sm3_test_12345678" data_bytes = data.encode('utf-8') # 计算SM3哈希值 sm3_hash = sm3.sm3_hash(func.bytes_to_list(data_bytes)) sm3_hash2 = digest(data_bytes) sm3_hash2 = ''.join(f'{byte:02x}' for byte in sm3_hash2) print("gmssl库生成->", sm3_hash) print("自定义函数生成->", sm3_hash2) test_sm3()
最后的输出结果
gmssl库生成-> 78d24683f804ada766f92313843548a357dbc9adaa6aae95902db1b031e8b1a0
自定义函数生成-> 78d24683f804ada766f92313843548a357dbc9adaa6aae95902db1b031e8b1a0
和GMSSL库生成的完全一致,说明自定义的函数实现是符合标准算法的。