Java 加密技术全面解析:SM2、SM4、MD5 及常用加密方法
Java 加密技术全面解析:SM2、SM4、MD5 及常用加密方法
前言
在现代软件开发中,数据安全是至关重要的。无论是用户隐私信息(如手机号、身份证号)还是敏感业务数据,都需要通过加密技术来保护。Java 提供了丰富的加密工具和算法,本文将详细介绍常用的加密技术,包括国密算法(SM2、SM4)、MD5、AES 等,并给出代码示例、优缺点分析以及适用场景。
目录
- 加密技术概述
- 国密算法:SM2 和 SM4
- 常用加密方法:MD5、AES、RSA
- 手机号、身份证号等隐私信息的加密方法
- 总结与最佳实践
1. 加密技术概述
加密技术主要分为两类:
- 对称加密:加密和解密使用相同的密钥,如 SM4、AES。
- 非对称加密:加密和解密使用不同的密钥(公钥和私钥),如 SM2、RSA。
此外,哈希算法(如 MD5)虽然不属于加密算法,但常用于数据完整性校验和密码存储。
2. 国密算法:SM2 和 SM4
2.1 SM2(非对称加密)
SM2 是中国国家密码管理局发布的非对称加密算法,基于椭圆曲线密码学(ECC)。
代码示例
java
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Security;
public class SM2Example {
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
// 生成密钥对
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "BC");
keyPairGenerator.initialize(256);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// 加密
SM2Engine sm2Engine = new SM2Engine();
sm2Engine.init(true, new ECPublicKeyParameters(keyPair.getPublic()));
byte[] plaintext = "Hello, SM2!".getBytes();
byte[] ciphertext = sm2Engine.processBlock(plaintext, 0, plaintext.length);
System.out.println("密文: " + Hex.toHexString(ciphertext));
// 解密
sm2Engine.init(false, new ECPrivateKeyParameters(keyPair.getPrivate()));
byte[] decryptedText = sm2Engine.processBlock(ciphertext, 0, ciphertext.length);
System.out.println("明文: " + new String(decryptedText));
}
}
优缺点
- 优点:安全性高,密钥长度短,适合资源受限的环境。
- 缺点:实现复杂,依赖第三方库(如 BouncyCastle)。
- 适用场景:数字签名、密钥交换、数据加密。
2.2 SM4(对称加密)
SM4 是中国国家密码管理局发布的对称加密算法,分组长度为 128 位。
代码示例
java
import org.bouncycastle.crypto.engines.SM4Engine;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
import java.security.Security;
public class SM4Example {
public static void main(String[] args) {
Security.addProvider(new BouncyCastleProvider());
byte[] key = Hex.decode("0123456789abcdeffedcba9876543210");
byte[] plaintext = "Hello, SM4!".getBytes();
// 加密
SM4Engine sm4Engine = new SM4Engine();
sm4Engine.init(true, new KeyParameter(key));
byte[] ciphertext = new byte[sm4Engine.getOutputSize(plaintext.length)];
int len = sm4Engine.processBlock(plaintext, 0, ciphertext, 0);
System.out.println("密文: " + Hex.toHexString(ciphertext));
// 解密
sm4Engine.init(false, new KeyParameter(key));
byte[] decryptedText = new byte[sm4Engine.getOutputSize(ciphertext.length)];
len = sm4Engine.processBlock(ciphertext, 0, decryptedText, 0);
System.out.println("明文: " + new String(decryptedText));
}
}
优缺点
- 优点:安全性高,适合国产化环境。
- 缺点:实现复杂,依赖第三方库。
- 适用场景:数据加密、文件加密。
3. 常用加密方法
3.1 MD5(哈希算法)
MD5 是一种广泛使用的哈希算法,常用于数据完整性校验和密码存储。
代码示例
java
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Example {
public static void main(String[] args) throws NoSuchAlgorithmException {
String input = "Hello, MD5!";
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] hash = md5.digest(input.getBytes());
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
hexString.append(String.format("%02x", b));
}
System.out.println("MD5 哈希值: " + hexString);
}
}
优缺点
- 优点:计算速度快,适合数据校验。
- 缺点:存在碰撞风险,不适合密码存储。
- 适用场景:数据完整性校验、文件校验。
3.2 AES(对称加密)
AES 是一种广泛使用的对称加密算法,支持 128、192 和 256 位密钥。
代码示例
java
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.util.Base64;
public class AESExample {
public static void main(String[] args) throws Exception {
// 生成密钥
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128);
SecretKey secretKey = keyGen.generateKey();
// 加密
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] ciphertext = cipher.doFinal("Hello, AES!".getBytes());
System.out.println("密文: " + Base64.getEncoder().encodeToString(ciphertext));
// 解密
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedText = cipher.doFinal(ciphertext);
System.out.println("明文: " + new String(decryptedText));
}
}
优缺点
- 优点:安全性高,性能好。
- 缺点:密钥管理复杂。
- 适用场景:数据加密、文件加密。
3.3 RSA(非对称加密)
RSA 是一种广泛使用的非对称加密算法,适合密钥交换和数字签名。
代码示例
java
import javax.crypto.Cipher;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.util.Base64;
public class RSAExample {
public static void main(String[] args) throws Exception {
// 生成密钥对
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// 加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
byte[] ciphertext = cipher.doFinal("Hello, RSA!".getBytes());
System.out.println("密文: " + Base64.getEncoder().encodeToString(ciphertext));
// 解密
cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
byte[] decryptedText = cipher.doFinal(ciphertext);
System.out.println("明文: " + new String(decryptedText));
}
}
优缺点
- 优点:安全性高,适合密钥交换和数字签名。
- 缺点:性能较差,密钥长度较长。
- 适用场景:密钥交换、数字签名。
4. 手机号、身份证号等隐私信息的加密方法
对于手机号、身份证号等隐私信息,常用的加密方法包括:
4.1 对称加密(如 AES)
- 使用 AES 对数据进行加密,密钥由系统管理。
- 代码示例:
java
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.util.Base64;
public class AESPrivacyExample {
public static void main(String[] args) throws Exception {
// 生成密钥
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128);
SecretKey secretKey = keyGen.generateKey();
// 加密手机号
String phoneNumber = "13812345678";
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedPhone = cipher.doFinal(phoneNumber.getBytes());
System.out.println("加密后的手机号: " + Base64.getEncoder().encodeToString(encryptedPhone));
// 解密手机号
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedPhone = cipher.doFinal(encryptedPhone);
System.out.println("解密后的手机号: " + new String(decryptedPhone));
}
}
4.2 脱敏处理
- 对部分信息进行脱敏,例如手机号显示为
138****1234
。 - 代码示例:
java
public class DesensitizationExample {
public static void main(String[] args) {
String phoneNumber = "13812345678";
String desensitizedPhone = phoneNumber.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
System.out.println("脱敏后的手机号: " + desensitizedPhone);
}
}
4.3 哈希算法(如 SHA-256)
- 对数据进行哈希处理,存储哈希值。
- 代码示例:
java
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class SHA256Example {
public static void main(String[] args) throws NoSuchAlgorithmException {
String phoneNumber = "13812345678";
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
byte[] hash = sha256.digest(phoneNumber.getBytes());
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
hexString.append(String.format("%02x", b));
}
System.out.println("SHA-256 哈希值: " + hexString);
}
}
5. 总结与最佳实践
- 选择合适算法:根据场景选择对称加密、非对称加密或哈希算法。
- 密钥管理:妥善管理密钥,避免泄露。
- 隐私保护:对敏感信息进行加密或脱敏处理。
- 性能优化:在高频场景下选择性能较好的算法(如 AES)。
通过合理使用加密技术,可以有效保护数据安全,提升系统的健壮性和可靠性。
参考资料
- BouncyCastle 官方文档
- Java 加密与解密技术
- 《Java 加密与解密的艺术》