一、简介
RSA公开密钥密码体制是一种使用不同的加密密钥与解密密钥,在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。
正是基于这种理论,1978年出现了著名的RSA算法,它通常是先生成一对RSA密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为提高保密强度,RSA密钥至少为500位长。这就使加密的计算量很大。为减少计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA对话密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。对方收到信息后,用不同的密钥解密并可核对信息摘要 。
RSA是被研究得最广泛的公钥算法,从提出到现在已近三十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。
二、应用
1、密匙生成器,自动生成gongshi公钥和私钥,其中1024为密匙大小,密钥可以设置的范围是96-1024
keyPairGen.initialize(1024,new SecureRandom());
2、公钥加密,先获取公钥publicKey,进行cipher初始化,对data进行加密。
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes("UTF-8")));
3、私钥解密,先获取私钥privateKey,进行cipher初始化,对data进行转换,在进行解密。
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] inputByte = Base64.getDecoder().decode(data.getBytes("UTF-8"));
new String(cipher.doFinal(inputByte),"UTF-8");
三、代码
1、运行代码:
package demo;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.util.Base64;
import javax.crypto.Cipher;
public class RSAUtil {
//自动创建生成公钥和私钥对(RSA算法)
public static KeyPair getKeyPair() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(1024,new SecureRandom());
KeyPair keyPair = keyPairGen.generateKeyPair();
return keyPair;
}
//公钥加密
public static String encryption(String data, Key publicKey) throws Exception{
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
String information = Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes("UTF-8")));
return information;
}
//私钥解密
public static String decrypt(String data, Key privateKey) throws Exception{
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] inputByte = Base64.getDecoder().decode(data.getBytes("UTF-8"));
String information = new String(cipher.doFinal(inputByte),"UTF-8");
return information;
}
//私钥生成签名
public static String sign(String data, PrivateKey privateKey) throws Exception {
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(data.getBytes(StandardCharsets.UTF_8));
byte[] inputByte = signature.sign();
return Base64.getEncoder().encodeToString(inputByte);
}
//公钥验证签名
public static boolean validate(String data, String sign, PublicKey publicKey) throws Exception {
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(publicKey);
signature.update(data.getBytes(StandardCharsets.UTF_8));
byte[] inputByte = Base64.getDecoder().decode(sign);
return signature.verify(inputByte);
}
public static void main(String[] args) throws Exception {
System.out.println("====================================================================");
KeyPair keyPair = getKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
String data0 = "RSA加密解密成功!";
System.out.println("==公钥:"+keyPair.getPublic());
System.out.println("==私钥:"+keyPair.getPrivate());
System.out.println("加密前数据:"+data0);
String data1 = encryption(data0,publicKey);
System.out.println("加密后数据:"+data1);
String messageDe = decrypt(data1,privateKey);
System.out.println("解密后数据:"+messageDe);
String sign = sign(data0, keyPair.getPrivate());
boolean validate = validate(data0,sign, keyPair.getPublic());
System.out.println("校验通过:"+validate);
System.out.println("====================================================================");
}
}
运行结果: