当前位置: 首页 > news >正文

JavaScript逆向SM国密算法

JavaScript逆向SM国密算法

  • 什么是SM国密
  • SM国密算法分类
    • SM2 - 非对称加密算法
      • JavaScript实现
      • Python 实现
    • SM3 - 摘要算法
      • JavaScript实现
      • Python 实现
    • SM4 - 对称加密算法
      • JavaScript实现
      • Python 实现
  • 逆向技巧
    • 案例

什么是SM国密

SM 国密 指的是由中国国家密码管理局(State Cryptography Administration)发布的一系列国家商用密码标准

简单来说,“国密”是中国自主研发、拥有完全自主知识产权的一套密码算法体系

  • SM 是“商用密码”的拼音首字母缩写。
  • 国密 指的是国家密码标准。

这套体系的诞生,其核心战略目标是实现信息安全领域的自主可控,摆脱对国际通用加密算法(主要是由美国设计和标准化的算法,如 AES、RSA、SHA-2 等)的依赖,确保在中国境内的关键信息基础设施和重要领域的数据安全。

SM国密算法分类

SM2 - 非对称加密算法

  • 类型: 非对称加密 (公钥加密)

  • 技术基础: 椭圆曲线密码学 (ECC)

  • 主要功能:

    • 加密/解密: 类似于 RSA,用于保证数据机密性。
    • 数字签名: 类似于 RSA 和 ECDSA,用于身份认证和数据完整性校验。
    • 密钥交换: 类似于 ECDH,用于安全地协商会话密钥。
  • 对标的国际算法: RSA, ECDH, ECDSA。SM2 的主要优势是,与 RSA 相比,它能用更短的密钥长度达到同等的安全级别,计算效率更高。

JavaScript实现

需先安装sm-crypto

npm install sm-crypto
// --- 1. 引入 sm-crypto 库 ---// 在 Node.js 环境中:
const smCrypto = require('sm-crypto');
const { sm2 } = smCrypto;// 在浏览器环境中,smCrypto 是一个全局变量,sm2 可以这样获取:
// const { sm2 } = smCrypto;// --- 2. 生成 SM2 密钥对 ---
console.log("✅ 1. 正在生成 SM2 密钥对...");
const keyPair = sm2.generateKeyPairHex();
const publicKey = keyPair.publicKey;   // 获取十六进制格式的公钥
const privateKey = keyPair.privateKey; // 获取十六进制格式的私钥console.log("公钥:", publicKey);
console.log("私钥:", privateKey);// --- 3. 示例 1: 加密与解密 ---
console.log("\n--- 示例 1: 加密与解密 ---");const messageToEncrypt = "这是一条需要SM2加密的机密信息。";
console.log("原始消息:", messageToEncrypt);// 使用公钥进行加密
// 注意:加密结果默认会带一个 '04' 的前缀
// cipherMode: 1 表示 C1C3C2 模式,这是国密标准顺序
const encrypted = sm2.encrypt(messageToEncrypt, publicKey, {cipherMode: 1 
});
console.log("加密后的十六进制:", encrypted);// 使用私钥进行解密
const decrypted = sm2.decrypt(encrypted, privateKey, {cipherMode: 1
});
console.log("解密后的消息:", decrypted);
console.log("验证成功:", messageToEncrypt === decrypted);// --- 4. 示例 2: 签名与验证 ---
console.log("\n--- 示例 2: 签名与验证 ---");const messageToSign = "这条消息需要签名以验证来源。";
console.log("待签名的消息:", messageToSign);// 使用私钥对消息进行签名
const signature = sm2.doSignature(messageToSign, privateKey);
console.log("生成的签名 (十六进制):", signature);// 使用公钥验证签名
const isVerified = sm2.doVerifySignature(messageToSign, signature, publicKey);
console.log("签名是否有效:", isVerified);// 尝试用一个被篡改的消息进行验证
const tamperedMessage = "这条消息是伪造的!";
const isTamperedVerified = sm2.doVerifySignature(tamperedMessage, signature, publicKey);
console.log("篡改后消息的签名是否有效:", isTamperedVerified);

Python 实现

需先安装gmssl

pip install gmssl
from gmssl import sm2, func# 1. --- 生成 SM2 密钥对 ---
print("✅ 1. 正在生成 SM2 密钥对...")# 创建 sm2.CryptSM2 实例来处理密钥和加解密
sm2_crypt = sm2.CryptSM2()# sm2_crypt 实例在创建时会自动生成密钥对
private_key = sm2_crypt.private_key # 这是一个大整数
public_key = sm2_crypt.public_key   # 这是一个椭圆曲线上的点 (x, y)# 为了方便展示和传输,我们通常使用十六进制格式
private_key_hex = hex(private_key)[2:]
public_key_hex = public_key.hex()print(f"生成的私钥 (Hex): {private_key_hex}")
print(f"生成的公钥 (Hex): {public_key_hex}")# --- 2. 示例 1: 加密与解密 ---
print("\n--- 示例 1: 加密与解密 ---")message_to_encrypt = "这是一条需要SM2加密的机密信息。"
# 在 Python 中,加密操作处理的是字节 (bytes),所以需要编码
message_bytes = message_to_encrypt.encode('utf-8')
print(f"原始消息: '{message_to_encrypt}'")# 使用公钥进行加密
encrypted = sm2_crypt.encrypt(message_bytes)
# 加密后的结果是字节,我们使用十六进制编码以便显示
encrypted_hex = encrypted.hex()
print(f"加密后的十六进制: {encrypted_hex}")# 使用私钥进行解密
decrypted_bytes = sm2_crypt.decrypt(encrypted)
decrypted_message = decrypted_bytes.decode('utf-8')
print(f"解密后的消息: '{decrypted_message}'")
print(f"验证成功: {message_to_encrypt == decrypted_message}")# --- 3. 示例 2: 签名与验证 ---
print("\n--- 示例 2: 签名与验证 ---")message_to_sign = "这条消息需要签名以验证来源。"
message_bytes_to_sign = message_to_sign.encode('utf-8')# SM2 签名标准中,通常需要一个用户ID (ID_A),如果没有可以是一个默认值
user_id = '1234567812345678'
print(f"待签名的消息: '{message_to_sign}'")# 使用私钥对消息进行签名
# 注意:gmssl 的 sign 方法返回的是一个签名的字节表示
signature = sm2_crypt.sign(message_bytes_to_sign, user_id.encode('utf-8'))
signature_hex = signature.hex()
print(f"生成的签名 (十六进制): {signature_hex}")# 使用公钥验证签名
# verify 方法返回一个布尔值
is_verified = sm2_crypt.verify(signature, message_bytes_to_sign, user_id.encode('utf-8'))
print(f"签名是否有效: {is_verified}")# 尝试用一个被篡改的消息进行验证
tampered_message = b"This message is tampered!"
is_tampered_verified = sm2_crypt.verify(signature, tampered_message, user_id.encode('utf-8'))
print(f"篡改后消息的签名是否有效: {is_tampered_verified}")

SM3 - 摘要算法

  • 类型: 密码摘要算法 (哈希函数)
  • 主要功能: 生成数据的唯一“数字指纹”,用于验证数据完整性、数字签名等。
  • 输出长度: 256 位
  • 对标的国际算法: SHA-256。SM3 的算法结构与 SHA-256 类似,但在设计细节上有所不同,目前被认为是安全的。

JavaScript实现

需先安装sm-crypto

npm install sm-crypto
// --- 1. 引入 sm-crypto 库 ---// 在 Node.js 环境中:
const smCrypto = require('sm-crypto');
const { sm3 } = smCrypto;// 在浏览器环境中,smCrypto 是一个全局变量,sm3 可以这样获取:
// const { sm3 } = smCrypto;// --- 2. 准备要计算哈希的消息 ---
const message1 = "1";
const message2 = "这是一条需要计算SM3哈希的消息。";
const message3 = "This is a message that needs to be hashed by SM3.";// --- 3. 执行哈希计算 ---
console.log("✅ 正在执行 SM3 哈希计算...");const hash1 = sm3(message1);
const hash2 = sm3(message2);
const hash3 = sm3(message3);console.log(`
原始消息: "${message1}"
SM3 哈希值: ${hash1}
`);console.log(`
原始消息: "${message2}"
SM3 哈希值: ${hash2}
`);console.log(`
原始消息: "${message3}"
SM3 哈希值: ${hash3}
`);// 演示雪崩效应:只修改一个字符
const message4 = "This is a message that needs to be hashed by SM4."; // 3 -> 4
const hash4 = sm3(message4);
console.log(`
修改后的消息: "${message4}"
SM3 哈希值: ${hash4}
`);

Python 实现

需先安装gmssl

pip install gmssl
from gmssl import sm3# --- 准备要计算哈希的消息 ---
message1 = "1"
message2 = "这是一条需要计算SM3哈希的消息。"# --- 执行哈希计算 ---
print("✅ 正在执行 SM3 哈希计算 (函数式调用)...")# 关键:必须将输入字符串编码为字节 (bytes)
message1_bytes = message1.encode('utf-8')
message2_bytes = message2.encode('utf-8')# 调用 sm3_hash 函数
hash_bytes1 = sm3.sm3_hash(message1_bytes)
hash_bytes2 = sm3.sm3_hash(message2_bytes)# 计算出的结果是字节类型,我们通常将其转换为十六进制字符串以便显示
hash_hex1 = hash_bytes1.hex()
hash_hex2 = hash_bytes2.hex()print(f"""
原始消息: "{message1}"
SM3 哈希值: {hash_hex1}
""")
# 预期输出: 164b71b213c8b67279e88afe5847b71f543a29b53141f53e023f79568b20d860print(f"""
原始消息: "{message2}"
SM3 哈希值: {hash_hex2}
""")
# 预期输出: f841f32a762c21958b493e83884214b62f43a4a159f893118021183187c337d1

SM4 - 对称加密算法

  • 类型: 对称加密 - 分组密码
  • 主要功能: 对大量数据进行高效的加密和解密。
  • 分组长度: 128 位
  • 密钥长度: 128 位
  • 对标的国际算法: AES-128。SM4 的加密轮数、S盒设计等与 AES 不同,也是一个非常健壮的分组密码算法。它最初用于中国的无线局域网标准(WAPI)

JavaScript实现

需先安装sm-crypto

npm install sm-crypto
// --- 1. 引入 sm-crypto 库 ---// 在 Node.js 环境中:
const smCrypto = require('sm-crypto');
const { sm4 } = smCrypto;// 在浏览器环境中,smCrypto 是一个全局变量,sm4 可以这样获取:
// const { sm4 } = smCrypto;// --- 2. 准备加密所需的参数 ---
const message = "这是一条需要使用SM4进行对称加密的机密信息。";// 密钥 (Key):必须是 16 字节 (128位)。这里我们用一个 16 个字符的字符串,
// 然后转换为十六进制。在实际应用中,密钥应该是随机生成的。
const key = '0123456789abcdeffedcba9876543210'; // 16 字节的十六进制密钥// 初始化向量 (IV):必须是 16 字节 (128位)。
const iv = '0123456789abcdeffedcba9876543210'; // 16 字节的十六进制 IV// --- 3. 执行加密 ---
console.log("✅ 正在执行 SM4 加密 (CBC 模式)...");
console.log("原始消息:", message);// 使用 sm4.encrypt(message, key, options)
const encrypted = sm4.encrypt(message, key, {iv: iv,mode: 'cbc', // 指定为 CBC 模式padding: 'pkcs7' // 默认填充方式
});console.log("加密后的十六进制:", encrypted);// --- 4. 执行解密 ---
console.log("\n✅ 正在执行 SM4 解密 (CBC 模式)...");// 使用 sm4.decrypt(encryptedHex, key, options)
const decrypted = sm4.decrypt(encrypted, key, {iv: iv,mode: 'cbc',padding: 'pkcs7'
});console.log("解密后的消息:", decrypted);
console.log("验证成功:", message === decrypted);

Python 实现

需先安装gmssl

pip install gmssl

确保 pycryptodome 也已安装,以使用其方便的填充功能

pip install pycryptodome
from gmssl import sm4
from Crypto.Util.Padding import pad, unpad
import base64# --- 1. 准备加密所需的参数 ---
message = "这是一条需要使用SM4进行对称加密的机密信息。"# 密钥 (Key):必须是 16 字节的 bytes 类型
key = b'0123456789abcdef'# 初始化向量 (IV):必须是 16 字节的 bytes 类型
iv = b'fedcba9876543210'print("--- 加解密参数 ---")
print(f"原始消息: '{message}'")
print(f"使用的密钥: {key}")
print(f"使用的 IV: {iv}")
print("-----------------------------------------")# --- 2. 加密函数 ---
def encrypt_sm4_cbc(plain_text, key, iv):"""使用 SM4-CBC 模式加密文本"""# 将明文消息编码为字节plain_text_bytes = plain_text.encode('utf-8')# 创建一个 SM4 加密器实例cipher = sm4.CryptSM4()cipher.set_key(key, sm4.SM4_ENCRYPT)# 对明文进行 PKCS7 填充,使其长度是 16 字节的整数倍padded_bytes = pad(plain_text_bytes, sm4.SM4_BLOCK_SIZE)# 执行 CBC 模式加密encrypted_bytes = cipher.crypt_cbc(iv, padded_bytes)# 将加密后的字节转换为 Base64 编码的字符串,以便传输return base64.b64encode(encrypted_bytes).decode('utf-8')# --- 3. 解密函数 ---
def decrypt_sm4_cbc(encrypted_b64, key, iv):"""使用 SM4-CBC 模式解密文本"""# 将 Base64 字符串解码回字节encrypted_bytes = base64.b64decode(encrypted_b64)# 创建一个 SM4 解密器实例decipher = sm4.CryptSM4()decipher.set_key(key, sm4.SM4_DECRYPT)# 执行 CBC 模式解密decrypted_padded_bytes = decipher.crypt_cbc(iv, encrypted_bytes)# 去除填充,得到原始的字节数据unpadded_bytes = unpad(decrypted_padded_bytes, sm4.SM4_BLOCK_SIZE)# 将字节解码回我们可读的字符串return unpadded_bytes.decode('utf-8')# --- 4. 执行并验证 ---
print("正在加密...")
encrypted_message = encrypt_sm4_cbc(message, key, iv)
print(f"加密后的 Base64 字符串: {encrypted_message}")
print("-----------------------------------------")print("正在解密...")
decrypted_message = decrypt_sm4_cbc(encrypted_message, key, iv)
print(f"解密后的消息: '{decrypted_message}'")
print("-----------------------------------------")print(f"验证解密是否成功: {message == decrypted_message}")

逆向技巧

案例


文章转载自:

http://w4g1cHKo.jwtjf.cn
http://EzA1vRM6.jwtjf.cn
http://GGQhOvkY.jwtjf.cn
http://1RiZGE4f.jwtjf.cn
http://POTyc08T.jwtjf.cn
http://v9Y4cyBC.jwtjf.cn
http://YYFkueKA.jwtjf.cn
http://c2megjna.jwtjf.cn
http://sadYvgMR.jwtjf.cn
http://DAKCkZtz.jwtjf.cn
http://0Jv6hTE6.jwtjf.cn
http://manAJVbS.jwtjf.cn
http://XnXevsnt.jwtjf.cn
http://1s0bz9ye.jwtjf.cn
http://5SvUBS44.jwtjf.cn
http://wRQZ27gX.jwtjf.cn
http://ZaUbygTi.jwtjf.cn
http://5IHYqYD7.jwtjf.cn
http://0Efh2GRP.jwtjf.cn
http://WSWUmoSB.jwtjf.cn
http://fjE1X8mz.jwtjf.cn
http://7lwNPGbM.jwtjf.cn
http://pabvhjgX.jwtjf.cn
http://tedYYy5Z.jwtjf.cn
http://loTXp1nX.jwtjf.cn
http://Q2v5Y1Y0.jwtjf.cn
http://IfJiA0l1.jwtjf.cn
http://2nm6Wcku.jwtjf.cn
http://0BkGgabZ.jwtjf.cn
http://OLx0AmKq.jwtjf.cn
http://www.dtcms.com/a/379538.html

相关文章:

  • 炫彩VS动作指令:活体检测技术大比拼
  • 只读查询的“零分配”之路:EF Core + Dapper + MemoryPack 的组合优化
  • EMC电磁兼容进阶3讲培训:专题三 近场探头和频谱仪在EMC整改中的应用
  • 清理C盘回忆录
  • 对于单链表相关经典算法题:21. 合并两个有序链表及面试题 02.04. 分割链表的解析
  • 【代码随想录day 24】 力扣 78.集合
  • leetcode算法刷题的第三十二天
  • (done) CUDA 和 CPU 性能对比,矩阵加法和矩阵乘法对比
  • 事实上事实上
  • 【左程云算法07】队列和栈-链表数组实现
  • 关于亚马逊账号关联的思考——关于侵权
  • 【硬件-笔试面试题-84】硬件/电子工程师,笔试面试题(知识点:MOS管是损耗有哪些)
  • mybatis vs mybatis-plus
  • 网络诊断和通信中非常重要的工具或协议
  • Mysql主键选取
  • 蓝桥杯嵌入式
  • Python学习——字典和文件
  • urllib的使用
  • AFSim2.9.0学习笔记 —— 4.1、创建项目,以此项目介绍工作中Wizard使用(红方/蓝方武器平台、阵营、更换图标等,多图详细介绍)
  • 机器人驭风而行:低空经济如何开启智能新纪元【科普类】
  • 【论文速读】LLM Compiler:并行函数调用的新范式
  • 【复习】计网每日一题---海明校验码
  • CVPR 2025最佳论文解读|VGGT:Visual Geometry Grounded Transformer
  • 深度学习里的树模型TabNet
  • 洛谷P5250 【深基17.例5】木材仓库 (集合法)详解
  • zsn的作品集
  • 磁共振成像原理(理论)6:自由感应衰减 (Free Induction Decays)
  • 第3节-使用表格数据-CHECK约束
  • 彻底解决Qt中文乱码以及汉字编码的问题(UTF-8/GBK)
  • 【观察】傅建平:迈向“数据强国”,打通数据要素化“任督二脉”的三把钥匙