不调用gmssl库,用python代码具体实现签名,验签过程,比如杂凑函数,随机生成素数p等
时间: 2024-03-23 21:43:38 浏览: 125
(纯算法,没有调用库)python实现RSA数字签名代码、ppt、文档.rar
5星 · 资源好评率100%
好的,以下是一个使用Python代码实现SM2签名和验签的示例:
```python
from hashlib import sha256
from random import randint
from sympy import isprime, primerange
# 杂凑函数使用SHA256
def hash(msg):
return sha256(msg).digest()
# 随机生成SM2私钥
def gen_private_key():
p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
d = randint(1, n - 1)
while not isprime(d):
d = randint(1, n - 1)
return d
# 生成SM2公钥
def gen_public_key(d):
p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
a = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2c
b = 0x28e9fa9e9d9f5e344d5a9e4bcf6509a7f39789f515ab8f92d5879b8543a1e
gx = 0x32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1711fe3c3eb9b67
gy = 0xbc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a
return sm2_point_mul(d, (gx, gy), a, p)
# SM2点乘
def sm2_point_mul(k, P, a, p):
Q = P
k2 = bin(k)[2:]
for i in range(1, len(k2)):
Q = sm2_point_add(Q, Q, a, p)
if k2[i] == '1':
Q = sm2_point_add(Q, P, a, p)
return Q
# SM2点加
def sm2_point_add(P, Q, a, p):
if P[0] == Q[0] and P[1] == Q[1]:
return sm2_point_double(P, a, p)
elif P[0] == Q[0] and P[1] == -Q[1] % p:
return (0, 0)
else:
lam = ((Q[1] - P[1]) * pow(Q[0] - P[0], p - 2, p)) % p
x = (lam**2 - P[0] - Q[0]) % p
y = (lam * (P[0] - x) - P[1]) % p
return (x, y)
# SM2点倍乘
def sm2_point_double(P, a, p):
if P[1] == 0:
return (0, 0)
else:
lam = ((3 * P[0]**2 + a) * pow(2 * P[1], p - 2, p)) % p
x = (lam**2 - 2 * P[0]) % p
y = (lam * (P[0] - x) - P[1]) % p
return (x, y)
# SM2签名
def sm2_sign(msg, d):
p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
e = int.from_bytes(hash(msg), 'big')
k = randint(1, n - 1)
while True:
x1, y1 = sm2_point_mul(k, (gx, gy), a, p)
r = (e + x1) % n
if r == 0 or r + k == n:
continue
s = ((1 + d) ** -1 * (k - r*d) % n)
if s == 0:
continue
else:
break
return (r, s)
# SM2验签
def sm2_verify(msg, Q, r, s):
p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
e = int.from_bytes(hash(msg), 'big')
if not (1 <= r <= n - 1 and 1 <= s <= n - 1):
return False
t = (r + s) % n
if t == 0:
return False
x1, y1 = sm2_point_mul((s**-1 * t) % n, (gx, gy), a, p)
x2, y2 = sm2_point_mul((s**-1 * r) % n, Q, a, p)
x, y = sm2_point_add((x1, y1), (x2, y2), a, p)
if r == (e + x) % n:
return True
else:
return False
# 测试代码
d = gen_private_key()
Q = gen_public_key(d)
msg = b"Hello, world!"
r, s = sm2_sign(msg, d)
if sm2_verify(msg, Q, r, s):
print("签名验证成功")
else:
print("签名验证失败")
```
其中,使用 `hashlib.sha256()` 函数实现杂凑函数,使用 `random.randint()` 函数生成私钥,使用 SymPy 库的 `isprime()` 和 `primerange()` 函数判断质数。使用 `sm2_point_mul()` 函数实现SM2点乘,使用 `sm2_point_add()` 函数实现SM2点加,使用 `sm2_point_double()` 函数实现SM2点倍乘。使用 `sm2_sign()` 函数实现SM2签名,使用 `sm2_verify()` 函数实现SM2验签。
需要注意的是,SM2签名中还涉及到Z值的计算,可以使用 `hash()` 函数进行计算。具体实现可以参考SM2密码算法标准。另外,本示例代码中的SM2参数为固定值,实际应用中需要根据具体情况进行调整。
希望这个示例代码对您有所帮助。
阅读全文