非对称加密算法需要两个密钥:公钥和私钥
公钥和私钥是一对的,如果用公钥数据进行加密,只有用对应的私钥才能解密:如果用私钥对数据加密,那么只有用公钥才能解密。
常见的算法:RSA、Elgamal等
应用场景:
1.银行/电商等网站,银行将公钥公布出去,大家都能使用,是要自己保存,用户传输过去的信息,只有银行能用私钥进行解密。
2.加密对称加密的密钥。
/**
* 非对称加密
*/
public class AsymmetricEncryption {
//一次性加密数据的长度不能大于117字节
private static final int ENCRYPT_BLOCK_MAX = 117;
//一次性解密的数据长度不能大于128字节
private static final int DECRYPT_BLOCK_MAX = 128;
public static void main(String[] args) throws Exception {
String content = "黑马程序员";
//String content = "黑马程序员黑马程序员黑马程序员黑马程序员黑马程序员黑马程序员黑马程序员黑马程序员黑马程序员";
System.out.println("原文长度: " + content.getBytes().length);
//生成密钥对,并保存到磁盘上
generateKeyPair();
//加密
String result = encrypt(content);
System.out.println("加密: " + result);
//解密
String decryptResult = decrypt(result);
System.out.println("解密: " + decryptResult);
}
public static String encrypt(String content) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
PublicKey publicKey = (PublicKey) SerializableUtil.readObject("heima.publicKey");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
//不能一次性处理超过117字节大小的数据
//byte[] result = cipher.doFinal(content.getBytes());
//需要分批处理
byte[] result = doFinalWithBatch(content.getBytes(), cipher, ENCRYPT_BLOCK_MAX);
return Base64.encode(result);
}
public static String decrypt(String content) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
PrivateKey privateKey = (PrivateKey) SerializableUtil.readObject("heima.privateKey");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
//不能一次性处理超过117字节大小的数据
//byte[] result = cipher.doFinal(content.getBytes());
//需要分批处理
byte[] result = doFinalWithBatch(Base64.decode(content), cipher, DECRYPT_BLOCK_MAX);
return new String(result);
}
public static byte[] doFinalWithBatch(byte[] input, Cipher cipher, int blockSize) throws IllegalBlockSizeException, BadPaddingException, IOException {
byte[] tmp = null;
int offset = 0;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while (input.length - offset > 0) {
if (input.length - offset >= blockSize) {
tmp = cipher.doFinal(input, offset, blockSize);
offset = offset + blockSize;
}else {
tmp = cipher.doFinal(input, offset, input.length - offset);
offset = offset + (input.length - offset);
}
baos.write(tmp);
}
baos.close();
return baos.toByteArray();
}
public static void generateKeyPair() throws NoSuchAlgorithmException, IOException {
//通过秘钥对生成器KeyPairGenerator生成公钥和私钥
KeyPair keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
//使用公钥进行加密,私钥进行解密(也可以反过来使用)
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
//将公钥、私钥序列化到磁盘上
SerializableUtil.saveObject(publicKey, "heima.publicKey");
SerializableUtil.saveObject(privateKey, "heima.privateKey");
}
}