Java Cipher 是 Java 加密标准库中的一个类,用于实现各种密码算法的加密和解码操作。
加密防止内容被泄露 ;签名防止内容被篡改。常用非对称加密 RSA、DSA;对称加密 AES、DES
非对称加密算法都可以在 Java 的 Cipher 类中通过指定相应的算法名称来使用。例如,使用 Cipher.getInstance(“RSA”) 可以获取一个用于 RSA 加密和解密的 Cipher 对象。
注意:每种非对称加密算法可能还有不同的工作模式和填充方式可供选择,在使用 Cipher 进行非对称加密时,也需要根据具体需求进行相应的设置。
◯ RSA:RSA(Rivest-Shamir-Adleman) 是一种基于大数因子分解的非对称加密算法。最常用的非对称加密算法之一,加密解密数据,生成和验证数据签名。
◯ DSA:DSA(Digital Signature Algorithm) 用于生成和验证数字签名的非对称加密算法。验证数据的完整性和身份认证。
◯ ECIES:ECIES(Elliptic Curve Integrated Encryption Scheme) 基于椭圆曲线密码学的非对称加密算法。
◯ Elgamal:Elgamal 是一种基于离散对数问题的非对称加密算法。它可以用于加密和解密数据以及生成和验证数字签名。
注意:具体可用的对称加密算法取决于 Java 运行时环境的配置,不同的 Java 版本和供应商可能支持不同的算法。可通过调用 Cipher.getMaxAllowedKeyLength() 方法来查看支持的最大密钥长度。 此外,为了确保数据的安全性,建议使用具有强大安全性和广泛接受的加密算法,如 AES 。同时,也要正确处理密钥管理、加密模式和填充方式等方面的问题。
不推荐 AES/ECB 组合使用
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
public class CipherExample {
public static void main(String[] args) throws Exception {
// 生成AES密钥
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128); // 指定密钥长度为128位
SecretKey secretKey = keyGenerator.generateKey();
// 创建Cipher对象并初始化
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
// 加密数据
String plainText = "Hello, World!";
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedText = cipher.doFinal(plainText.getBytes());
System.out.println("加密后的数据:" + new String(encryptedText));
// 解密数据
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedText = cipher.doFinal(encryptedText);
System.out.println("解密后的数据:" + new String(decryptedText));
}
}
推荐 AES/CBC
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class AesCbcDemo {
public static void main(String[] args) throws Exception {
String plaintext = "Hello, world!"; // 待加密的原始文本
String secretKey = "0123456789abcdef"; // 16字节的密钥(128位)
// 将密钥转换为相应的对象
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes("UTF-8"), "AES");
// 创建AES加密器和解密器对象
Cipher encryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
Cipher decryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// 初始化加密器和解密器
byte[] ivBytes = new byte[encryptCipher.getBlockSize()];
IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
encryptCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
decryptCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
// 加密
byte[] encryptedBytes = encryptCipher.doFinal(plaintext.getBytes("UTF-8"));
// 将加密结果进行Base64编码,以便展示和传输
String encryptedText = Base64.getEncoder().encodeToString(encryptedBytes);
System.out.println("加密后:" + encryptedText);
// 解密
byte[] decryptedBytes = decryptCipher.doFinal(Base64.getDecoder().decode(encryptedText));
String decryptedText = new String(decryptedBytes, "UTF-8");
System.out.println("解密后:" + decryptedText);
}
}
RSA/CBC 一般 RSA 不与 CBC 组合使用,而与 ECB 组合
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
public static void main(String[] args) throws Exception {
// 生成RSA密钥对
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048); // 设置密钥长度为2048位
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
System.out.println("publicKey: " + publicKey);
System.out.println("privateKey: " + privateKey);
// 明文
String plainText = "Hello, World!";
// 加密 可替换 RSA/ECB/OAEPWithSHA-256AndMGF1Padding
Cipher encryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedBytes = encryptCipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
System.out.println("加密后的数据:" + new String(encryptedBytes));
// 解密 可替换 RSA/ECB/OAEPWithSHA-256AndMGF1Padding
Cipher decryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedBytes = decryptCipher.doFinal(encryptedBytes);
System.out.println("解密后的数据:" + new String(decryptedBytes));
}