一、RSA介绍
RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。
RSA算法是一种非对称加密算法,与对称加密算法不同的是,RSA算法有两个不同的密钥,一个是公钥,一个是私钥。
RSA公开密钥密码体制是一种使用不同的加密密钥与解密密钥,“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制 。
在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK 。
正是基于这种理论,1978年出现了著名的RSA算法,它通常是先生成一对RSA密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为提高保密强度,RSA密钥至少为500位长。这就使加密的计算量很大。为减少计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA对话密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。对方收到信息后,用不同的密钥解密并可核对信息摘要 。
RSA是被研究得最广泛的公钥算法,从提出后经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。1983年麻省理工学院在美国为RSA算法申请了专利 。
非对称加密之RSA加密解密
二、公钥、私钥
a、公钥:用于数据的加密,可以公开共享
b、私钥:用于数据的解密,需要妥善保管,不能泄露
公钥只能用于加密数据,私钥只能用于解密数据,二者不可更换使用,即用公钥加密的数据只能使用对应的私钥进行解密,反之亦然。
三、对应的加解密实践
public static void main(String[] args) throws Exception{
String password = "Cc123456";
// 将公钥和私钥的Base64编码字符串转换为PublicKey和PrivateKey对象
String publicKeyBase64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCAmmOLsLvqW9puLqvdChcvUFZhtWAxqQ1nP+3uokDxGwWuh3hnJ4nk2vD9QlDQ/deOJPwo0kB2yL4XEe3OJ3rr1wUdcOvYEq7IXNnL98L0LDEHgj4RN9f72XE7h7thOgBCsPh9Eea3QkBa00RYg6VZNq9brioLNWE4QfWxq/QpdQIDAQAB";
String privateKeyBase64 = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAICaY4uwu+pb2m4uq90KFy9QVmG1YDGpDWc/7e6iQPEbBa6HeGcnieTa8P1CUND9144k/CjSQHbIvhcR7c4neuvXBR1w69gSrshc2cv3wvQsMQeCPhE31/vZcTuHu2E6AEKw+H0R5rdCQFrTRFiDpVk2r1uuKgs1YThB9bGr9Cl1AgMBAAECgYBNrnSA9cGc390CfzibLTQyBUIYhTnU5XvOKWSsp9+4hA0bjoMhNFXsIoA9SuiMRTkGiLq0YcREvB9uygquY1Sw6hXdXT5g5WtO7jOm1TaFQbwMlP6hpZ8RskuLW5jm3WIP2MrN0lPry+zknfBLHnGedrBOzzdWCFwg4257TEL4AQJBAPNrnGXvdWz0OdZB58XFsI4HqvBo890gM2nC7C6+pHBjMuOBkD9gmGvNkME/FP1cPMXXy0aOzVm343JSwzNq8gECQQCHP8ZVaeE5Bwl2U1zhBeg799mXZ8vWz4Hp7Vmq62dNLi/+wAPX3FQCKm+EbmTHQ/AzGvN45CIpsD4fPW/05Y91AkBaNidgH76FAn3syb/7q6gi+vR+5GZ8LNLg/zxIlp6aiCjz57BtzH6wdR6Qf7BntSdQqwjKvWGdPmkslT+CbsABAkEAhXsDmzir90Riqk0L1WmnEchDD5J5MsAJT33YiT9a7GkxJRMMt/XTU2/eL61j+OWsIkPvFtjQfqRaKyrPW7tUIQJAG06KnfaYli7nlI7n6cjpcEkA5iTIsV5bgIjzIsTa1ewad9ywunKox2mqDPpgqMH3CjPfygnHFoNPl0ukfYfcmw==";
PublicKey publicKey = KeyFactory.getInstance("RSA")
.generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyBase64)));
PrivateKey privateKey = KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyBase64)));
// 使用公钥加密数据
Cipher encryptCipher = Cipher.getInstance("RSA");
encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedBytes = encryptCipher.doFinal(password.getBytes());
//密文作为参数传输到后端时+号变成了空格,"+"替换成"_"
String result =Base64.getEncoder().encodeToString(encryptedBytes).replace("+","_");
// 使用私钥解密数据
Cipher decryptCipher = Cipher.getInstance("RSA");
decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedBytes = decryptCipher.doFinal(encryptedBytes);
String decryptedText = new String(decryptedBytes);
System.out.println("加密后的数据: " + result);
System.out.println("解密后的数据: " + decryptedText);
}