非对称加密算法(2):RSA

来源:互联网 发布:iPad看视频软件 编辑:程序博客网 时间:2024/06/15 11:03

一.RSA:RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。1987年7月首次在美国公布,当时他们三人都在麻省理工学院工作实习。RSA就是他们三人姓氏开头字母拼在一起组成的。


RSA算法基于一个十分简单的数论事实:将两个大质数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。


二.优缺点:

1)产生密钥很麻烦,受到素数产生技术的限制,因而难以做到一次一密。
2)安全性,RSA的安全性依赖于大数的因子分解,但并没有从理论上证明破译RSA的难度与大数分解难度等价,而且密码学界多数人士倾向于因子分解不是NP问题。
3)速度太慢,由于RSA 的分组长度太大,为保证安全性,n 至少也要 600 bits以上,使运算代价很高,尤其是速度较慢,较对称密码算法慢几个数量级;且随着大数分解技术的发展,这个长度还在增加,不利于数据格式的标准化。SET(Secure Electronic Transaction)协议中要求CA采用2048比特长的密钥,其他实体使用1024比特的密钥。为了速度问题,人们广泛使用单,公钥密码结合使用的方法,优缺点互补:单钥密码加密速度快,人们用它来加密较长的文件,然后用RSA来给文件密钥加密,极好的解决了单钥密码的密钥分发问题。

三.实现过程:


四.具体的实现代码(java):

import java.security.InvalidKeyException;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.PrivateKey;import java.security.PublicKey;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.InvalidKeySpecException;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import org.apache.commons.codec.binary.Base64;/** * 使用 RSA 算法对数据进行加解密   * @author wsy  */public class RSA {static String src = "欧阳草帽";public static void main(String[] args) throws Exception {//初始化秘钥KeyPair keyPair = getKeyPair();RSAPublicKey rsaPublicKey = getPublicKey(keyPair);RSAPrivateKey rsaPrivateKey = getPrivateKey(keyPair);//私钥加密,公钥解密  ---- 加密 byte[] result = encryptedByPublic(rsaPrivateKey,src);System.out.println("加密结果:"+Base64.encodeBase64String(result));//私钥加密,公钥解密  ---- 解密 result = decryptByPrivate(rsaPublicKey, result);System.out.println("解密结果:"+new String(result));//公钥加密,公私钥解密  ---- 加密 result = encryptByPrivate(rsaPublicKey, src);System.out.println("加密结果 :"+Base64.encodeBase64String(result));//公钥加密,公私钥解密  ---- 解密 result = decryptByPublic(rsaPrivateKey, result);System.out.println("解密结果:"+new String(result));}/** * 私钥加密,公钥解密    ---  解密 * @param rsaPrivateKey * @param encryptBytes * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */public static byte[] decryptByPublic(RSAPrivateKey rsaPrivateKey,byte[] encryptBytes) throws NoSuchAlgorithmException,InvalidKeySpecException, NoSuchPaddingException,InvalidKeyException, IllegalBlockSizeException, BadPaddingException {PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());KeyFactory keyFactory = KeyFactory.getInstance("RSA");PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] result = cipher.doFinal(encryptBytes);  // 解密结果 return result;}/** * 私钥加密,公钥解密    ---  加密 * @param rsaPublicKey * @param src * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */public static byte [] encryptByPrivate(RSAPublicKey rsaPublicKey, String src)throws NoSuchAlgorithmException, InvalidKeySpecException,NoSuchPaddingException, InvalidKeyException,IllegalBlockSizeException, BadPaddingException {X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());KeyFactory keyFactory = KeyFactory.getInstance("RSA");PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, publicKey);byte [] result = cipher.doFinal(src.getBytes()); //加密结果 return result;}/** * 公钥加密,私钥解密    ---  解密 * @param rsaPublicKey * @param encryptBytes * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */public static byte[] decryptByPrivate(RSAPublicKey rsaPublicKey,byte[] encryptBytes) throws NoSuchAlgorithmException,InvalidKeySpecException, NoSuchPaddingException,InvalidKeyException, IllegalBlockSizeException, BadPaddingException {X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());KeyFactory keyFactory = KeyFactory.getInstance("RSA");PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, publicKey);byte[] result = cipher.doFinal(encryptBytes); //解密结果 return result;}/** * 公钥加密,私钥解密    ---  加密  * @param rsaPrivateKey * @param src * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */public static byte[] encryptedByPublic(RSAPrivateKey rsaPrivateKey,String src)throws NoSuchAlgorithmException, InvalidKeySpecException,NoSuchPaddingException, InvalidKeyException,IllegalBlockSizeException, BadPaddingException {PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());KeyFactory keyFactory = KeyFactory.getInstance("RSA");PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, privateKey);byte [] result = cipher.doFinal(src.getBytes());  // 加密结果 return result;}/** * 获取私钥 * @param keyPair * @return */public static RSAPrivateKey getPrivateKey(KeyPair keyPair) {RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();return rsaPrivateKey;}/** * 获取公钥 * @param keyPair * @return */public static RSAPublicKey getPublicKey(KeyPair keyPair) {RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();return rsaPublicKey;}private static KeyPair getKeyPair() throws NoSuchAlgorithmException {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(512);KeyPair keyPair = keyPairGenerator.generateKeyPair();return keyPair;}}