RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。1987年7月首次在美国公布,当时他们三人都在麻省理工学院工作实习。RSA就是他们三人姓氏开头字母拼在一起组成的。
RSA是目前最有影响力和最常用的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。
RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。
在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。
基于这种理论,1978年出现了著名的RSA算法,它通常是先生成一对RSA 密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可以在网络服务器中注册。为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位。这就使加密的计算量很大。
RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA是被研究得最广泛的公钥算法,从提出到现今的三十多年里,经历了各种攻击的考验,逐渐为人们接受,截止2017年被普遍认为是最优秀的公钥方案之一。
SET(Secure Electronic Transaction)协议中要求CA采用2048bits长的密钥,其他实体使用1024比特的密钥。RSA密钥长度随着保密级别提高,增加很快。
RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。
我们接下来看下Java中如何实现RSA加密解密与加签验签。我们先来看RSA加密解密。
1 import javax.crypto.BadPaddingException; 2 import javax.crypto.Cipher; 3 import javax.crypto.IllegalBlockSizeException; 4 import javax.crypto.NoSuchPaddingException; 5 import java.security.*; 6 import java.util.Base64; 7 /** 8 * RSA加密解密操作步骤 9 */ 10 public class Test1 { 11 public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { 12 //先给出一个待加密的字符串 13 String data="青青子衿,悠悠我心。但为君故,沉吟至今。"; 14 //1.构建公私钥匙对 15 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); 16 KeyPair keyPair = keyPairGenerator.generateKeyPair(); 17 //2.获取钥匙对中的公钥 18 PublicKey publicKey = keyPair.getPublic(); 19 //3.获取钥匙对中的私钥 20 PrivateKey privateKey = keyPair.getPrivate(); 21 //4.对待加密的数据进行加密 22 Cipher cipher = Cipher.getInstance("RSA"); 23 cipher.init(Cipher.ENCRYPT_MODE,publicKey); 24 byte[] bytesEncrypt = cipher.doFinal(data.getBytes());//产生的是乱码,需要用Base64进行转码 25 //5.Base64编码 26 byte[] encodeBase64 = Base64.getEncoder().encode(bytesEncrypt); 27 System.out.println("加密后的数据:"+new String(encodeBase64)); 28 //6.在解密时,先对用Base64编码的信息进行解码 29 byte[] bytesDecode = Base64.getDecoder().decode(encodeBase64); 30 //7.解密 31 Cipher cipher2=Cipher.getInstance("RSA"); 32 cipher2.init(Cipher.DECRYPT_MODE,privateKey); 33 byte[] bytesDecrypt = cipher2.doFinal(bytesDecode); 34 System.out.println("解密后的数据:"+new String(bytesDecrypt)); 35 } 36 }