国密算法
作者:YXN-python 阅读量:155 发布日期:2025-04-08
国密算法
国密算法由中国国家密码管理局(SMAC)发布的自主可控密码算法体系,用于替代国际通用算法(如RSA、AES等)。
算法分类:
- 哈希算法:SM3
- 对称加密算法:SM1、SM4、SM7、祖冲之算法(ZUC)
- 非对称算法:SM2、SM9
- 目前最常见的就是SM2、SM3、SM4
算法 | 类型 | 密钥/哈希长度 | 对标算法 | 特点 |
SM2 | 非对称加密 | 256位 | RSA | 加密、解密以及签名、验证速度相对RSA更为高效,密钥更短 |
SM3 | 密码哈希 | 256位 | SHA-256 | 基于SHA-256改进,安全性高于MD5和SHA-1 |
SM4 | 对称加密 | 128位 | AES-128 | 加密速度快,适合大规模数据处理,安全性对标 AES |
数字签名及验证:
SM2、RSA等非对称算法(公钥加密,私钥解密。私钥数字签名,公钥验证) 数字签名的基本原理: 签名:发送方 1、对原始数据(如文件、消息)应用哈希算法(如SHA-256)生成固定长度的哈希值 2、使用私钥加密哈希值(SM2签名验证默认的使用SM3),形成数字签名 验证:接收方 1、对收到的原始数据重新计算哈希值 2、用公钥解密签名,得到发送方生成的哈希值 3、对比两个哈希值:若一致则验证通过,否则数据可能被篡改或签名无效
Python实现SM2、SM3、SM4加密解密以及SM2签名验证
from gmssl import sm2,sm3,sm4,func
# 明文字节串形式
data = 'Python'.encode('utf-8')
# -------------------------------------------------------------------------------------
# ----------------------------SM2加密与解密、签名与验证------------------------------------
# 密钥
private_key = '00b9ab0b828ff68872f21a837fc303668428dea11dcd1b24429d0c99e24eed83d5'
public_key = "b9c9a6e04e9c91f7ba880429273747d7ef5ddeb0bb2ff6317eb00bef331a83081a6994b8993f3f5d6eadddb81872266c87c018fb4162f5af347b483e24620207"
# 绑定密钥
sm2_crypt = sm2.CryptSM2(public_key=public_key, private_key=private_key)
# 加密
SM2_encrypted_data = sm2_crypt.encrypt(data)
print(SM2_encrypted_data.hex())
# 和RSA一样每次加密的值不同
# 输出:abb997aba628b9d3529fdd6ca3e61ce79cb55c4399baa873e62f1bbc17d0597f8c43cd75e4a17592f69eb54a7ae7556c29dd3fff71f002bef2156e9573c2c1facc14eae3fc989781ac9380f8e5339c1d6d223944d4f7e9b70df252d4de8926a16fdca64a7d57
# 解密
SM2_decrypted_data = sm2_crypt.decrypt(SM2_encrypted_data)
print(SM2_decrypted_data.decode('utf-8'))
# Python
# 签名
# 生成安全随机数
random_hex_str = func.random_hex(sm2_crypt.para_len)
# 签名
sign = sm2_crypt.sign(data, random_hex_str)
print(sign)
# 输出:b855643cd0697b02c7e7309c68ad1b52ca7e14f56de2b3a1be3be58b1f958fa876ddd36cc6bd695a84177671bb88e4c99e6016f5fe36ba78f2ead10594673eeb
# 验证
verify = sm2_crypt.verify(sign, data)
print(verify)
# 输出:True
# -------------------------------------------------------------------------------------
# -------------------------------------------------------------------------------------
# ----------------------------SM3加密与解密、签名与验证------------------------------------
# 将编码后的字节序列转换为一个 bytes 对象,国密SM3要求加密的数据类型是bytes类型
data_list = [i for i in bytes(data)]
# 加密
SM3_encrypted_data = sm3.sm3_hash(data_list)
print(SM3_encrypted_data)
# 输出:154175d585ba2a79db4bb8cb8b08c7c511d8217e9888a9fb48cb02cbe7a9539b
# -------------------------------------------------------------------------------------
# -------------------------------------------------------------------------------------
# ----------------------------SM4加密与解密、签名与验证------------------------------------
# 密钥和IV
key = '0123456789abcdef'.encode()
iv = 'fedcba9876543210'.encode()
# 创建SM4加密对象
crypt_sm4 = sm4.CryptSM4()
# 加密(CBC模式)
crypt_sm4.set_key(key, sm4.SM4_ENCRYPT)
SM4_encrypted_data = crypt_sm4.crypt_cbc(iv, data)
print(SM4_encrypted_data.hex())
# 输出:baad9b269b3eabba41c30db3a10e9d79
# 解密(CBC模式)
crypt_sm4.set_key(key, sm4.SM4_DECRYPT)
decrypted_data = crypt_sm4.crypt_cbc(iv, SM4_encrypted_data)
print(decrypted_data.decode('utf-8'))
# 输出:Python
JavaScript实现SM2、SM3、SM4加密解密以及SM2签名验证
npm install sm-crypto
// 引入sm-crypto库
const smCrypto = require('sm-crypto');
// 明文数据
const data = 'JavaScript';
// -------------------------------------------------------------------------------------
// ----------------------------SM2加密与解密、签名与验证------------------------------------
// 密钥生成
const keypair = smCrypto.sm2.generateKeyPairHex(); // { privateKey, publicKey }
// 加密模式
// 0 C1C2C3
// 1 C1C3C2
// 默认是为1
const cipherMode = 1;
// 加密
const SM2_encrypted_data= smCrypto.sm2.doEncrypt(data, keypair.publicKey, cipherMode);
console.log(SM2_encrypted_data)
// 和RSA一样每次加密的值不同
// 输出:556aa79b44207def50ba4dfa93736315e25bb11f757c334a980bf00b7f1affac16afc3ed6d618b4b352a78c901bd24e4fdad8aca1cdbf7cc77b4c1765a5c165ba88b3dc6fcb63d838f68a9b3bc51fb69d4ea8d6288a6cb26f06da5ab5ebf0e14d508208cfeda645d6b99
// 解密
const SM2_decrypted_data = smCrypto.sm2.doDecrypt(SM2_encrypted_data, keypair.privateKey, cipherMode);
console.log(SM2_decrypted_data)
// 输出:JavaScript
// 签名
const SM2_sign = smCrypto.sm2.doSignature(data, keypair.privateKey);
console.log(SM2_sign)
// 和RSA一样每次加密的值不同
// 输出:268788fd8121e39b9a787bc98402339281e076f7d0a8eb56680fb1c246119bfe25d021a9a8fd57a8c86d5190f033da464465fb36d6321423a7b4ff2811c676f6
// 验证
const SM2_verifyResult = smCrypto.sm2.doVerifySignature(data, SM2_sign, keypair.publicKey);
console.log(SM2_verifyResult)
// 输出:true
// -------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------
// ---------------------------------SM3加密解密------------------------------------------
// 使用sm-crypto库进行SM3加密
const SM3_data = smCrypto.sm3(data).toString();
console.log(SM3_data);
// 输出:7594992e5b4ba778ab169fb37a0cba720a1c349ffb61f0a361f3ebddeec8b739
// -------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------
// ---------------------------------SM4加密解密------------------------------------------
// 密钥 iv
const iv = "1234567887654321abcdefghhgfedcba";
const key = '0123456789abcdeffedcba9876543210';
// 加密
const SM4_encrypted_data = smCrypto.sm4.encrypt(data, key, {
mode: 'cbc',
iv: iv,
output: 'base64'
});
console.log(SM4_encrypted_data);
// 输出:f6edcda2f66484ac4b865ffbc5c27723
// 解密
const SM4_decrypted_data = smCrypto.sm4.decrypt(SM4_encrypted_data, key, {
mode: 'cbc',
iv: iv,
});
console.log(SM4_decrypted_data);
// 输出:JavaScript
YXN-python
2025-04-08