Java编程实现非对称加密的方法详解
非对称加密算法需要公钥和私钥。公钥可以对任意一个字符串进行加密,但只能用对应的私钥进行解密;私钥可以对任何一个字符串进行解密,但是只有对应的公钥能够进行加密。
生成密钥对
Java提供了多种非对称加密算法,比如RSA算法。使用Java生成RSA密钥对的过程如下:
import java.security.KeyPair;
import java.security.KeyPairGenerator;
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048); // 初始化密钥长度为2048位
KeyPair keyPair = keyPairGenerator.genKeyPair();
byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();
实例化 KeyPairGenerator 对象可以通过其提供者或者算法名称实现,这里我们使用 RSA 算法,密钥长度为2048位。调用 genKeyPair 方法就可以获得 KeyPair 对象。通过 getPublic 和 getPrivate 方法可以获取 PublicKey 和 PrivateKey,再使用 getEncoded 方法转换成二进制格式的字节串,方便存储或传输。
加密
使用公钥加密一个字符串:
import java.security.PublicKey;
import javax.crypto.Cipher;
String plainText = "Hello, world.";
byte[] publicKeyBytes = ...; // 获取公钥的二进制格式字节串
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
实例化 PublicKey 对象需要通过 KeyFactory 和 X509EncodedKeySpec 进行转换,在 Cipher 中使用公钥和 ENCRYPT_MODE 初始化后,调用 doFinal 方法将明文转换为密文(字节数组)。
解密
使用私钥解密上一步所得到的密文:
import java.security.PrivateKey;
byte[] privateKeyBytes = ...; // 获取私钥的二进制格式字节串
PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
String plainText = new String(decryptedBytes, "UTF-8");
同样地,实例化 PrivateKey 对象需要通过 KeyFactory 和 PKCS8EncodedKeySpec 进行转换,在 Cipher 中使用私钥和 DECRYPT_MODE 初始化后,调用 doFinal 方法将密文转换为明文。
示例说明
示例 1:加密字符串并进行解密
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import javax.crypto.Cipher;
public class AsymmetricEncryptionExample {
public static void main(String[] args) throws Exception {
String plainText = "Hello, world.";
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048); // 初始化密钥长度为2048位
KeyPair keyPair = keyPairGenerator.genKeyPair();
byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes));
PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
System.out.println("Encrypted: " + new String(encryptedBytes, "UTF-8"));
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
String decryptedText = new String(decryptedBytes, "UTF-8");
System.out.println("Decrypted: " + decryptedText);
}
}
输出:
Encrypted: ?0Mf???F???n@G?P?4?p??jd?g?z$?F?5?Xv?
Decrypted: Hello, world.
示例 2:使用公钥加密并传输密文,使用私钥解密
// 发送端
public class AsymmetricEncryptionExample {
public static void main(String[] args) throws Exception {
String plainText = "Hello, world.";
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048); // 初始化密钥长度为2048位
KeyPair keyPair = keyPairGenerator.genKeyPair();
byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
System.out.println("Encrypted: " + new String(encryptedBytes, "UTF-8"));
// 假设将 encryptedBytes 转换成Base64编码的字符串,传给接收端
}
}
// 接收端
public class AsymmetricEncryptionExample {
public static void main(String[] args) throws Exception {
byte[] encryptedBytes = ...; // 假设获取到 Base64 编码的密文,解码成字节数组
byte[] privateKeyBytes = ...; // 获取私钥的二进制格式字节串
PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
String decryptedText = new String(decryptedBytes, "UTF-8");
System.out.println("Decrypted: " + decryptedText);
}
}
输出:
Decrypted: Hello, world.
在示例2中,发送端和接收端都需要获取密钥对中的公钥或私钥。为了简便起见,这里省略了从文件、数据库等外部存储中获取密钥的部分。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java编程实现非对称加密的方法详解 - Python技术站