# Python中怎么使用SM4算法
## 1. 什么是SM4算法
SM4算法是中國國家密碼管理局于2012年發布的國家標準(GB/T 32907-2016),是一種分組對稱加密算法。它采用128位分組長度和128位密鑰長度,與AES算法類似但設計上有所不同。
### 1.1 SM4算法特點
- **國產密碼標準**:中國自主研發的商業密碼算法
- **安全性高**:經過嚴格密碼分析,抗差分和線性攻擊能力強
- **高效實現**:適合軟硬件實現,加解密速度與AES相當
- **應用廣泛**:在金融、政務等領域有強制使用要求
## 2. Python實現SM4的環境準備
### 2.1 安裝密碼學庫
Python中可通過以下庫實現SM4:
```bash
# 安裝gmssl庫(推薦)
pip install gmssl
# 或者安裝pycryptodome(需自行實現SM4)
pip install pycryptodome
from gmssl import sm4
print("SM4模塊加載成功")
from gmssl import sm4
def sm4_encrypt(key, plaintext):
"""
SM4加密函數
:param key: 16字節密鑰
:param plaintext: 明文數據
:return: 密文字節串
"""
crypt_sm4 = sm4.CryptSM4()
crypt_sm4.set_key(key, sm4.SM4_ENCRYPT)
encrypt_value = crypt_sm4.crypt_ecb(plaintext)
return encrypt_value
key = b'1234567890abcdef' # 16字節密鑰
data = b'Hello SM4 World!'
ciphertext = sm4_encrypt(key, data)
print("加密結果:", ciphertext.hex())
from gmssl import sm4
import binascii
class SM4Crypto:
def __init__(self, key):
if len(key) != 16:
raise ValueError("SM4密鑰必須為16字節")
self.key = key
self.block_size = 16
def encrypt(self, plaintext):
"""ECB模式加密"""
crypt_sm4 = sm4.CryptSM4()
crypt_sm4.set_key(self.key, sm4.SM4_ENCRYPT)
# 填充處理
padded_data = self._pad(plaintext)
ciphertext = crypt_sm4.crypt_ecb(padded_data)
return ciphertext
def decrypt(self, ciphertext):
"""ECB模式解密"""
crypt_sm4 = sm4.CryptSM4()
crypt_sm4.set_key(self.key, sm4.SM4_DECRYPT)
plaintext = crypt_sm4.crypt_ecb(ciphertext)
return self._unpad(plaintext)
def _pad(self, data):
"""PKCS#7填充"""
pad_len = self.block_size - (len(data) % self.block_size)
return data + bytes([pad_len] * pad_len)
def _unpad(self, data):
"""PKCS#7去填充"""
pad_len = data[-1]
return data[:-pad_len]
# 使用示例
key = b'1' * 16 # 16字節密鑰
sm4 = SM4Crypto(key)
original = b"Sensitive data需要加密"
print("原文:", original)
encrypted = sm4.encrypt(original)
print("密文:", binascii.hexlify(encrypted))
decrypted = sm4.decrypt(encrypted)
print("解密:", decrypted.decode())
SM4支持多種加密模式,以下是常見模式的實現:
from gmssl import sm4
import os
def sm4_cbc_encrypt(key, iv, plaintext):
crypt_sm4 = sm4.CryptSM4()
crypt_sm4.set_key(key, sm4.SM4_ENCRYPT)
return crypt_sm4.crypt_cbc(iv, plaintext)
def sm4_cbc_decrypt(key, iv, ciphertext):
crypt_sm4 = sm4.CryptSM4()
crypt_sm4.set_key(key, sm4.SM4_DECRYPT)
return crypt_sm4.crypt_cbc(iv, ciphertext)
# 使用示例
key = os.urandom(16) # 隨機生成密鑰
iv = os.urandom(16) # 初始化向量
data = b"Data to encrypt with CBC mode"
encrypted = sm4_cbc_encrypt(key, iv, data)
decrypted = sm4_cbc_decrypt(key, iv, encrypted)
print("CBC模式解密結果:", decrypted)
def encrypt_file(key, in_file, out_file):
"""加密文件"""
iv = os.urandom(16)
crypt_sm4 = sm4.CryptSM4()
crypt_sm4.set_key(key, sm4.SM4_ENCRYPT)
with open(in_file, 'rb') as fin, open(out_file, 'wb') as fout:
fout.write(iv) # 寫入IV
while True:
chunk = fin.read(1024)
if not chunk:
break
if len(chunk) % 16 != 0:
chunk += b' ' * (16 - len(chunk) % 16)
encrypted = crypt_sm4.crypt_cbc(iv, chunk)
fout.write(encrypted)
def decrypt_file(key, in_file, out_file):
"""解密文件"""
crypt_sm4 = sm4.CryptSM4()
crypt_sm4.set_key(key, sm4.SM4_DECRYPT)
with open(in_file, 'rb') as fin, open(out_file, 'wb') as fout:
iv = fin.read(16)
while True:
chunk = fin.read(1024)
if not chunk:
break
decrypted = crypt_sm4.crypt_cbc(iv, chunk)
fout.write(decrypted)
# 使用示例
key = b'my-secret-key-16b'
encrypt_file(key, 'plain.txt', 'encrypted.bin')
decrypt_file(key, 'encrypted.bin', 'decrypted.txt')
# 優化示例:重用SM4對象
crypt_sm4 = sm4.CryptSM4()
crypt_sm4.set_key(key, sm4.SM4_ENCRYPT)
for data in large_data_chunks:
encrypted = crypt_sm4.crypt_ecb(data)
# 處理加密數據
# OpenSSL命令行加密(需支持SM4)
openssl enc -sm4-cbc -in plain.txt -out encrypted.bin -K 密鑰16進制 -iv IV16進制
確保Java端使用BouncyCastle提供的SM4實現:
// Java端SM4示例代碼
Security.addProvider(new BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("SM4/CBC/PKCS7Padding", "BC");
SM4作為國密標準算法,在Python中的實現已經非常成熟。通過gmssl等庫可以方便地實現各種加密需求。實際使用時需要注意:
隨著國密算法的推廣,掌握SM4的使用將成為開發者的必備技能之一。
”`
這篇技術文章共計約2100字,全面介紹了Python中使用SM4算法的各種場景和注意事項,包含代碼示例、不同加密模式實現以及安全建議等內容。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。