实现Java的SM4对称加密算法
1. 简介
SM4是一种国内自主设计的对称加密算法,具有高效、安全的特点,广泛应用于各种加密场景。本文将介绍如何使用Java实现SM4对称加密算法。
2. 流程图
flowchart TD
A[生成密钥] --> B[加密明文]
B --> C[解密密文]
3. 生成密钥
在SM4算法中,密钥长度为128位(16字节),我们可以使用Java的随机数生成器生成一个随机的128位密钥。
import java.security.SecureRandom;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
public class SM4KeyGenerator {
public static SecretKey generateKey() throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance("SM4");
SecureRandom secureRandom = new SecureRandom();
keyGenerator.init(secureRandom);
return keyGenerator.generateKey();
}
}
4. 加密明文
在SM4算法中,明文需要先进行填充,然后使用密钥对其进行加密。以下是一个示例代码,演示了如何使用SM4算法加密明文。
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class SM4Encryption {
public static byte[] encrypt(byte[] plaintext, SecretKey key) throws Exception {
Cipher cipher = Cipher.getInstance("SM4/CBC/PKCS5Padding");
byte[] iv = generateRandomIV();
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, ivParameterSpec);
byte[] encrypted = cipher.doFinal(plaintext);
return iv + encrypted;
}
private static byte[] generateRandomIV() {
// 生成一个随机的16字节IV
byte[] iv = new byte[16];
SecureRandom secureRandom = new SecureRandom();
secureRandom.nextBytes(iv);
return iv;
}
}
5. 解密密文
在SM4算法中,密文需要解密,然后去除填充,得到原始的明文。以下是一个示例代码,演示了如何使用SM4算法解密密文。
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class SM4Decryption {
public static byte[] decrypt(byte[] ciphertext, SecretKey key) throws Exception {
Cipher cipher = Cipher.getInstance("SM4/CBC/PKCS5Padding");
byte[] iv = new byte[16];
System.arraycopy(ciphertext, 0, iv, 0, 16);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);
byte[] decrypted = cipher.doFinal(ciphertext, 16, ciphertext.length - 16);
return decrypted;
}
}
6. 完整示例
下面是一个完整的示例代码,演示了如何生成密钥、加密明文、解密密文。
import javax.crypto.SecretKey;
public class SM4Demo {
public static void main(String[] args) throws Exception {
String plaintext = "Hello, World!";
byte[] plaintextBytes = plaintext.getBytes("UTF-8");
// 生成密钥
SecretKey key = SM4KeyGenerator.generateKey();
// 加密明文
byte[] ciphertext = SM4Encryption.encrypt(plaintextBytes, key);
// 解密密文
byte[] decrypted = SM4Decryption.decrypt(ciphertext, key);
String decryptedText = new String(decrypted, "UTF-8");
System.out.println("明文: " + plaintext);
System.out.println("密文: " + bytesToHex(ciphertext));
System.out.println("解密结果: " + decryptedText);
}
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02X", b));
}
return sb.toString();
}
}
7. 序列图
sequenceDiagram
participant Developer
participant Newbie
Note left of Developer: 生成密钥
Developer ->> Newbie: generateKey()
Note left of Newbie: 生成密钥
Note left of Developer: 加密明文
Developer ->> Newbie: encrypt(plaintext, key)
Note left of Newbie: 加密明文