赞
踩
SM2是非对称加密算法
它是基于椭圆曲线密码的公钥密码算法标准,其秘钥长度256bit,包含数字签名、密钥交换和公钥加密,用于替换RSA/DH/ECDSA/ECDH等国际算法。可以满足电子认证服务系统等应用需求,由国家密码管理局于2010年12月17号发布。
SM2采用的是ECC 256位的一种,其安全强度比RSA 2048位高,且运算速度快于RSA。随着密码技术和计算技术的发展,目前常用的1024位RSA算法面临严重的安全威胁,我们国家密码管理部门经过研究,决定采用SM2椭圆曲线算法替换RSA算法。SM2算法在安全性、性能上都具有优势。
基础知识:椭圆曲线知识点、SM3算法
椭圆曲线方程: y 2 = x 3 + a x + b m o d p y^2=x^3+ax+b \mod p y2=x3+ax+bmodp
密钥对的生成:
一个很典型的例子:
a = 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC
b = 0x28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93
p = 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF
x_g = 0x32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7
y_g = 0xbc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0
n = 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123
M M M为待签名消息,数字签名结果为 ( r , s ) (r,s) (r,s) ,用户密钥对 ( d , P ) (d,P) (d,P)。
实现步骤:
M M M为明文, ( r , s ) (r,s) (r,s)为签名结果,用户公钥 P P P
实现步骤:
[ s ] G [s]G [s]G + [ t ] P [t]P [t]P的结果可以推导出等于 [ k ] G [k]G [k]G。
验证原理
[
s
]
G
+
[
t
]
P
=
s
G
+
(
r
+
s
)
P
[s]G+[t]P=sG+(r+s)P
[s]G+[t]P=sG+(r+s)P
=
s
G
+
(
r
+
s
)
d
G
\qquad \qquad \quad=sG+(r+s)dG
=sG+(r+s)dG
=
s
G
+
s
d
G
+
r
d
G
\qquad \qquad \quad=sG+sdG+rdG
=sG+sdG+rdG
=
(
1
+
d
)
s
G
+
r
d
G
\qquad \qquad \quad=(1+d)sG+rdG
=(1+d)sG+rdG
=
(
1
+
d
)
(
1
+
d
)
−
1
(
k
−
r
d
)
G
+
r
d
G
\qquad \qquad \quad=(1+d)(1+d)^{−1}(k−rd)G+rdG
=(1+d)(1+d)−1(k−rd)G+rdG
=
(
k
−
r
d
)
G
+
r
d
G
\qquad \qquad \quad=(k−rd)G+rdG
=(k−rd)G+rdG
=
k
G
−
r
d
G
+
r
d
G
\qquad \qquad \quad=kG−rdG+rdG
=kG−rdG+rdG
=
k
G
=
(
x
1
,
y
1
)
\qquad \qquad \quad=kG=(x1,y1)
=kG=(x1,y1)
M为明文字符串
C为密文字符串,klen为密文中C2的长度
首先,需要导入包gmssl
pip install gmssl
生成公私钥算法
sm2utils.py
from random import SystemRandom class CurveFp: def __init__(self, A, B, P, N, Gx, Gy, name): self.A = A self.B = B self.P = P self.N = N self.Gx = Gx self.Gy = Gy self.name = name sm2p256v1 = CurveFp( name="sm2p256v1", A=0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC, B=0x28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93, P=0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF, N=0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123, Gx=0x32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7, Gy=0xBC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0 ) def multiply(a, n, N, A, P): return fromJacobian(jacobianMultiply(toJacobian(a), n, N, A, P), P) def add(a, b, A, P): return fromJacobian(jacobianAdd(toJacobian(a), toJacobian(b), A, P), P) def inv(a, n): if a == 0: return 0 lm, hm = 1, 0 low, high = a % n, n while low > 1: r = high//low nm, new = hm-lm*r, high-low*r lm, low, hm, high = nm, new, lm, low return lm % n def toJacobian(Xp_Yp): Xp, Yp = Xp_Yp return (Xp, Yp, 1) def fromJacobian(Xp_Yp_Zp, P): Xp, Yp, Zp = Xp_Yp_Zp z = inv(Zp, P) return ((Xp * z**2) % P, (Yp * z**3) % P) def jacobianDouble(Xp_Yp_Zp, A, P): Xp, Yp, Zp = Xp_Yp_Zp if not Yp: return (0, 0, 0) ysq = (Yp ** 2) % P S = (4 * Xp * ysq) % P M = (3 * Xp ** 2 + A * Zp ** 4) % P nx = (M**2 - 2 * S) % P ny = (M * (S - nx) - 8 * ysq ** 2) % P nz = (2 * Yp * Zp) % P return (nx, ny, nz) def jacobianAdd(Xp_Yp_Zp, Xq_Yq_Zq, A, P): Xp, Yp, Zp = Xp_Yp_Zp Xq, Yq, Zq = Xq_Yq_Zq if not Yp: return (Xq, Yq, Zq) if not Yq: return (Xp, Yp, Zp) U1 = (Xp * Zq ** 2) % P U2 = (Xq * Zp ** 2) % P S1 = (Yp * Zq ** 3) % P S2 = (Yq * Zp ** 3) % P if U1 == U2: if S1 != S2: return (0, 0, 1) return jacobianDouble((Xp, Yp, Zp), A, P) H = U2 - U1 R = S2 - S1 H2 = (H * H) % P H3 = (H * H2) % P U1H2 = (U1 * H2) % P nx = (R ** 2 - H3 - 2 * U1H2) % P ny = (R * (U1H2 - nx) - S1 * H3) % P nz = (H * Zp * Zq) % P return (nx, ny, nz) def jacobianMultiply(Xp_Yp_Zp, n, N, A, P): Xp, Yp, Zp = Xp_Yp_Zp if Yp == 0 or n == 0: return (0, 0, 1) if n == 1: return (Xp, Yp, Zp) if n < 0 or n >= N: return jacobianMultiply((Xp, Yp, Zp), n % N, N, A, P) if (n % 2) == 0: return jacobianDouble(jacobianMultiply((Xp, Yp, Zp), n // 2, N, A, P), A, P) if (n % 2) == 1: return jacobianAdd(jacobianDouble(jacobianMultiply((Xp, Yp, Zp), n // 2, N, A, P), A, P), (Xp, Yp, Zp), A, P) class PrivateKey: def __init__(self, curve=sm2p256v1, secret=None): self.curve = curve self.secret = secret or SystemRandom().randrange(1, curve.N) def publicKey(self): curve = self.curve xPublicKey, yPublicKey = multiply((curve.Gx, curve.Gy), self.secret, A=curve.A, P=curve.P, N=curve.N) return PublicKey(xPublicKey, yPublicKey, curve) def toString(self): return "{}".format(str(hex(self.secret))[2:].zfill(64)) class PublicKey: def __init__(self, x, y, curve): self.x = x self.y = y self.curve = curve def toString(self, compressed=True): return { True: str(hex(self.x))[2:], False: "{}{}".format(str(hex(self.x))[2:].zfill(64), str(hex(self.y))[2:].zfill(64)) }.get(compressed) if __name__ == "__main__": priKey = PrivateKey() pubKey = priKey.publicKey() print(priKey.toString()) print(pubKey.toString(compressed = False))
加解密算法
封装类 sm2encryp.py
from gmssl import sm2 from base64 import b64encode, b64decode # sm2的公私钥 SM2_PRIVATE_KEY = '00B9AB0B828FF68872F21A837FC303668428DEA11DCD1B24429D0C99E24EED83D5' SM2_PUBLIC_KEY = 'B9C9A6E04E9C91F7BA880429273747D7EF5DDEB0BB2FF6317EB00BEF331A83081A6994B8993F3F5D6EADDDB81872266C87C018FB4162F5AF347B483E24620207' sm2_crypt = sm2.CryptSM2(public_key=SM2_PUBLIC_KEY, private_key=SM2_PRIVATE_KEY) class sm2Encrypt: # 加密 def encrypt(self, info): encode_info = sm2_crypt.encrypt(info.encode(encoding="utf-8")) encode_info = b64encode(encode_info).decode() # 将二进制bytes通过base64编码 return encode_info # 解密 def decrypt(self, info): decode_info = b64decode(info.encode()) # 通过base64解码成二进制bytes decode_info = sm2_crypt.decrypt(decode_info).decode(encoding="utf-8") return decode_info if __name__ == "__main__": origin_pwd = '123456' sm2 = sm2Encrypt() # 加密的密码 encrypy_pwd = sm2.encrypt(origin_pwd) print(encrypy_pwd) # 解密的密码 decrypt_pwd = sm2.decrypt(encrypy_pwd) print(decrypt_pwd)
当跟sm2encryp.py在一个文件夹是可以直接引用它
from sm2encryp import sm2Encrypt
pass_encrypt = sm2Encrypt()
pwd = pass_encrypt.decrypt("H24OlVZgSTtevCW138O+C5PlZp8OiD920JnpVr7r9ndkGBWFZUVDD48iIVrZRnamgosV5910m9k0438WpIyi0guEt8F5inG7Y5A51whRfdPZ+qdvWVQxI857CBEzkb3h1bMp1ETQ")
print(pwd)
https://www.jianshu.com/p/efc43060e0aa
https://blog.csdn.net/u013137970/article/details/84573200
https://blog.csdn.net/u014651560/article/details/113744296
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。