#!/usr/bin/env python3# -*- coding: utf-8 -*-
import osimport sysimport base64
try: from gmssl import sm3, sm4, funcexcept ImportError: print("检测到未安装gmssl库,正在尝试安装...") os.system("pip3 install gmssl==3.2.2") try: from gmssl import sm3, sm4, func except ImportError: print("安装gmssl库失败,请手动执行: pip3 install gmssl==3.2.2") sys.exit(1)
def print_menu(): print("\n===== 国密SM系列加解密工具 =====") print("1. SM3算法") print("2. SM4算法") print("3. 退出") return input("请选择功能 (1-3): ")
def sm3_menu(): while True: print("\n----- SM3算法 -----") print("1. 计算文本哈希") print("2. 计算文件哈希") print("3. 返回主菜单")
choice = input("请选择操作 (1-3): ")
if choice == "1": data = input("请输入要计算哈希的文本: ") try: hash_val = sm3.sm3_hash(func.bytes_to_list(data.encode())) print(f"SM3哈希结果: {hash_val}") except Exception as e: print(f"计算失败: {str(e)}")
elif choice == "2": file_path = input("请输入文件路径: ") try: hash_obj = sm3.SM3Hash() with open(file_path, "rb") as f: while True: chunk = f.read(4096) if not chunk: break hash_obj.update(func.bytes_to_list(chunk)) print(f"文件SM3哈希结果: {hash_obj.hexdigest()}") except Exception as e: print(f"计算失败: {str(e)}")
elif choice == "3": break
else: print("无效选择")
def sm4_menu(): key = None iv = None null_char = '\x00'
while True: print("\n----- SM4算法 -----") print("1. 生成密钥和IV") print("2. 手动输入密钥和IV") print("3. 加密 (ECB模式)") print("4. 解密 (ECB模式)") print("5. 加密 (CBC模式)") print("6. 解密 (CBC模式)") print("7. 返回主菜单")
choice = input("请选择操作 (1-7): ")
if choice == "1": key = os.urandom(16) iv = os.urandom(16) print(f"生成的密钥 (16字节): {key.hex()}") print(f"生成的IV (16字节): {iv.hex()}")
elif choice == "2": key_hex = input("请输入16字节密钥 (32个十六进制字符): ") if len(key_hex) != 32: print("密钥格式错误") continue
iv_hex = input("请输入16字节IV (32个十六进制字符,可选): ") if iv_hex and len(iv_hex) != 32: print("IV格式错误") continue
try: key = bytes.fromhex(key_hex) iv = bytes.fromhex(iv_hex) if iv_hex else None print("密钥输入成功") except Exception as e: print(f"格式错误: {str(e)}")
elif choice in ["3", "5"]: if not key: print("请先生成或输入密钥") continue
data = input("请输入要加密的数据: ") mode = "ECB" if choice == "3" else "CBC"
try: crypt_sm4 = sm4.CryptSM4() crypt_sm4.set_key(key, sm4.SM4_ENCRYPT)
if mode == "ECB": encrypted = crypt_sm4.crypt_ecb(data.encode()) else: if not iv: print("CBC模式需要IV,请先生成或输入IV") continue encrypted = crypt_sm4.crypt_cbc(iv, data.encode())
print(f"{mode}加密结果 (Base64): {base64.b64encode(encrypted).decode()}") except Exception as e: print(f"加密失败: {str(e)}")
elif choice in ["4", "6"]: if not key: print("请先生成或输入密钥") continue
data = input("请输入要解密的Base64数据: ") mode = "ECB" if choice == "4" else "CBC"
try: crypt_sm4 = sm4.CryptSM4() crypt_sm4.set_key(key, sm4.SM4_DECRYPT) encrypted_bytes = base64.b64decode(data)
if mode == "ECB": decrypted = crypt_sm4.crypt_ecb(encrypted_bytes) else: if not iv: print("CBC模式需要IV,请先生成或输入IV") continue decrypted = crypt_sm4.crypt_cbc(iv, encrypted_bytes)
print(f"{mode}解密结果: {decrypted.decode().rstrip(null_char)}") except Exception as e: print(f"解密失败: {str(e)}")
elif choice == "7": break
else: print("无效选择")
def main(): print("欢迎使用国密SM系列加解密工具") print("支持SM3哈希算法、SM4分组加密") while True: choice = print_menu() if choice == "1": sm3_menu() elif choice == "2": sm4_menu() elif choice == "3": print("感谢使用,再见!") break else: print("无效选择,请重新输入")
if __name__ == "__main__": main()