赞
踩
gmssl 是一个用于处理国密算法的 Python 模块,它提供了对国密算法的支持,包括对称加密、非对称加密、散列函数和数字签名等,仅列出了其中两个较为完善的第三方库,需要注意的是,SM1 和 SM7 算法不公开,目前大多库仅实现了 SM2、SM3、SM4 三种密算法。若要使用 SM9 算法,可下载 gmssl-python 源码手动安装
国密算法是中国自主研发的密码算法标准,相比于传统的国际标准算法,如 AES、RSA 等,国密算法具有以下优点和缺点:
优点:
1.安全性:国密算法经过严格的安全性评估和密码学专家的审查,具有较高的安全性。它们采用了更长的密钥长度和更复杂的算法设计,以抵御现代密码攻击。
2.自主可控:国密算法是中国自主研发的,不依赖于国外的算法标准和技术,有助于保护国家信息安全和数据主权。
3.高效性:国密算法在硬件和软件实现上进行了优化,具有较高的加密和解密速度,适用于大规模数据和高性能计算场景。
4.适应性:国密算法涵盖了对称加密、非对称加密、散列函数和数字签名等多个密码学领域,可以满足各种安全需求。
缺点:
1.兼容性:国密算法与传统的国际标准算法存在不兼容的问题,导致在与国际系统和标准进行交互时可能存在一些困难。
2.成熟度:相对于传统的国际标准算法,国密算法的应用和生态系统相对较新,可能在实际应用中还需要进一步的验证和完善。
3.开放性:国密算法的设计和实现细节相对闭源,对于研究者和开发者来说,了解和审计算法的难度较大。
需要注意的是,选择使用国密算法还是传统的国际标准算法应根据具体的应用场景和需求来决定。在保证安全性的前提下,要考虑到兼容性、生态系统支持以及算法的成熟度和广泛应用程度等因素。
pip install gmssl
gmssl.func 子模块提供了一些通用的功能函数,用于处理国密算法中常见的操作,例如编码转换、随机数生成、消息填充等。这些函数可以在使用国密算法时提供便利。
gmssl.sm2 子模块实现了 SM2 椭圆曲线公钥密码算法,该算法是国密算法体系中的非对称加密算法。它提供了生成密钥对、加密、解密、签名和验证等功能,用于实现 SM2 密钥交换、数据加密和数字签名等操作。
gmssl.sm3 子模块实现了 SM3 哈希算法,该算法是国密算法体系中的散列函数。它可以对输入数据进行哈希计算,生成固定长度的哈希值,用于数据完整性校验、密码存储和消息认证等场景
gmssl.sm4 子模块实现了 SM4 分组密码算法,该算法是国密算法体系中的对称加密算法。它提供了对称密钥的生成、加密和解密等功能,用于保护数据的机密性和保密性。
创建私钥、密钥生成文件,gmsslCreateKey.py,因为每次生成的key都不一样,可以把生成的key保存到文件中
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 CreatePrivateKey:
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 CreatePublicKey(xPublicKey, yPublicKey, curve)
def toString(self):
return "{}".format(str(hex(self.secret))[2:].zfill(64))
class CreatePublicKey:
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)
def create_key():
priKey = CreatePrivateKey()
pubKey = priKey.publicKey()
return priKey.toString(), pubKey.toString(compressed=False)
if __name__ == "__main__":
priKey = CreatePrivateKey()
pubKey = priKey.publicKey()
print(priKey.toString())
print(pubKey.toString(compressed=False))
from gmssl import sm2
from gmsslCreateKey import create_key
private_key,public_key = create_key()
data = b'Hello, SM2!'
cipher = sm2.CryptSM2(public_key=public_key,private_key=private_key) # 创建sm2对象
encrypted_data = cipher.encrypt(data)# 加密
decrypted_data = cipher.decrypt(encrypted_data)# 解密
print('原数据:', data)
print('加密后的数据:', encrypted_data)
print('解密后的数据:', decrypted_data)
import gmssl.func as gmssl_func
from gmssl import sm2
from gmsslCreateKey import create_key
private_key,public_key = create_key()
data = b'Hello, SM2!'
signer = sm2.CryptSM2(private_key=private_key, public_key=public_key) # 签名
random_hex = gmssl_func.random_hex(signer.para_len)
signature = signer.sign(data,random_hex)
verifier = sm2.CryptSM2(private_key=private_key, public_key=public_key) # 验证签名
is_valid = verifier.verify(signature, data)
print("签名数据:", data)
print("签名:", signature)
print("签名验证结果:", is_valid)
from gmssl import sm2
from gmsslCreateKey import create_key
private_key,public_key = create_key()
data = b'Hello, SM2!'
signer = sm2.CryptSM2(private_key=private_key, public_key=public_key) # 签名
sign = signer.sign_with_sm3(data) # 16进制
is_valid = signer.verify_with_sm3(sign, data) # 16进制
print("签名数据:", data)
print("签名:", sign)
print("签名验证结果:", is_valid)
import gmssl.func as gmssl_func
from gmssl import sm3
data = b"Hello, SM!" # bytes类型
sm3_hash = sm3.sm3_hash(gmssl_func.bytes_to_list(data))
print(sm3_hash)
import gmssl.func as gmssl_func
from gmssl import sm4
key = bytes([0] * 16)
data = b"Hello, SM4!" # 要加密的数据
sm4_crypt = sm4.CryptSM4() # 创建SM4加密对象
sm4_crypt.set_key(key, sm4.SM4_ENCRYPT) # 设置密钥
ciphertext = sm4_crypt.crypt_ecb(gmssl_func.bytes_to_list(data))# 加密数据
encrypted_data = bytes(gmssl_func.list_to_bytes(ciphertext))# 将加密后的数据转换为字节串
# 解密数据(如果需要)
sm4_crypt.set_key(key, sm4.SM4_DECRYPT)
decrypted_data = sm4_crypt.crypt_ecb(ciphertext)
decrypted_data = bytes(gmssl_func.list_to_bytes(decrypted_data))
print("原始数据:", data.decode("utf-8"))
print("加密后的数据:", encrypted_data.hex())
print("解密后的数据:", decrypted_data.decode("utf-8"))
import gmssl.func as gmssl_func
from gmssl import sm4
key = bytes([0] * 16)
data = b"Hello, SM4!" # 要加密的数据
iv = bytes([0] * 16) # bytes类型
sm4_crypt = sm4.CryptSM4() # 创建SM4加密对象
sm4_crypt.set_key(key, sm4.SM4_ENCRYPT) # 设置密钥
ciphertext = sm4_crypt.crypt_cbc(iv,gmssl_func.bytes_to_list(data))# 加密数据
encrypted_data = bytes(gmssl_func.list_to_bytes(ciphertext))# 将加密后的数据转换为字节串
# 解密数据(如果需要)
sm4_crypt.set_key(key, sm4.SM4_DECRYPT)
decrypted_data = sm4_crypt.crypt_ecb(ciphertext)
decrypted_data = bytes(gmssl_func.list_to_bytes(decrypted_data))
print("原始数据:", data.decode("utf-8"))
print("加密后的数据:", encrypted_data.hex())
print("解密后的数据:", decrypted_data.decode("utf-8"))
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。