Java非对称加密算法--RSA加密算法 原文http://blog.csdn.net/qiuzhping/article/details/44344373

来源:互联网 发布:沈阳seo那家好 编辑:程序博客网 时间:2024/06/02 05:13

Java非对称加密算法--RSA加密算法

         RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。

1973年,在英国政府通讯总部工作的数学家克利福德·柯克斯(Clifford Cocks)在一个内部文件中提出了一个相同的算法,但他的发现被列入机密,一直到1997年才被发表。

         对极大整数做因数分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。假如有人找到一种快速因数分解的算法的话,那么用RSA加密的信息的可靠性就肯定会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA钥匙才可能被强力方式解破。到2013年为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。

         下面我是采用Bouncy Castle实现的RSA加密算法。Bouncy Castle 是一种用于 Java 平台的开放源码的轻量级密码术包。它支持大量的密码术算法,并提供 JCE 1.2.1 的实现。因为 Bouncy Castle 被设计成轻量级的,所以从 J2SE 1.4 到 J2ME(包括 MIDP)平台,它都可以运行。它是在 MIDP 上运行的唯一完整的密码术包。

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:14px;">package com.qiuzhping.rsa;  
  2.   
  3. import org.bouncycastle.jce.provider.BouncyCastleProvider;  
  4.   
  5. import java.io.ByteArrayOutputStream;  
  6. import java.io.File;  
  7. import java.io.FileInputStream;  
  8. import java.io.FileOutputStream;  
  9. import java.io.ObjectInputStream;  
  10. import java.io.ObjectOutputStream;  
  11. import java.security.KeyPair;  
  12. import java.security.KeyPairGenerator;  
  13. import java.security.NoSuchAlgorithmException;  
  14. import java.security.PrivateKey;  
  15. import java.security.PublicKey;  
  16. import java.security.SecureRandom;  
  17.   
  18. import javax.crypto.Cipher;  
  19.   
  20. /** 
  21.  * 非对称加密是公钥加密,私钥来解密.使用的是Bouncy Castle 是一种用于 Java 平台的开放源码的轻量级密码术包. 
  22.  * 1、此Demo使用的是bcprov-ext-jdk15on-152.jar  
  23.  * 2、把jar文件复制到 $JAVA_HOME$\jre\lib\ext目录下面 
  24.  * 3、修改配置文件\jre\lib\security\java.security 
  25.  * security.provider.1=sun.security.provider.Sun 
  26.  * security.provider.2=sun.security.rsa.SunRsaSign 
  27.  * security.provider.3=com.sun.net.ssl.internal.ssl.Provider 
  28.  * security.provider.4=com.sun.crypto.provider.SunJCE 
  29.  * security.provider.5=sun.security.jgss.SunProvider 
  30.  * security.provider.6=com.sun.security.sasl.Provider 
  31.  * security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI 
  32.  * security.provider.8=sun.security.smartcardio.SunPCSC 上述8个是JDK已经实现了的加密方式. 将 
  33.  * security.provider.9=org.bouncycastle.jce.provider.BouncyCastleProvider 添加到后面. 
  34.  * 非对称加密称为公钥加密,算法更加复杂,速度慢,加密和解密钥匙不相同,任何人都可以知道公钥,只有一个人持有私钥可以解密。 
  35.  *  
  36.  * @author Peter.Qiu 
  37.  *  
  38.  */  
  39. public class RsaUtil {  
  40.   
  41.     /** 
  42.      * 根据publicKey 对data进行加密. 
  43.      *  
  44.      * @param publicKey 
  45.      * @param data 
  46.      * @throws Exception 
  47.      * @author Peter.Qiu 
  48.      */  
  49.     public static byte[] encryptMode(PublicKey publicKey, byte[] data)  
  50.             throws Exception {  
  51.         try {  
  52.             Cipher cipher = Cipher.getInstance("RSA",  
  53.                     new BouncyCastleProvider());  
  54.             cipher.init(Cipher.ENCRYPT_MODE, publicKey);// ENCRYPT_MODE 加密  
  55.             int blockSize = cipher.getBlockSize();  
  56.             int outputSize = cipher.getOutputSize(data.length);  
  57.             int leavedSize = data.length % blockSize;  
  58.             int blocksSize = leavedSize != 0 ? data.length / blockSize + 1  
  59.                     : data.length / blockSize;  
  60.             byte[] raw = new byte[outputSize * blocksSize];  
  61.             int i = 0;  
  62.             while (data.length - i * blockSize > 0) {  
  63.                 if (data.length - i * blockSize > blockSize) {  
  64.                     cipher.doFinal(data, i * blockSize, blockSize, raw, i  
  65.                             * outputSize);  
  66.                 } else {  
  67.                     cipher.doFinal(data, i * blockSize, data.length - i  
  68.                             * blockSize, raw, i * outputSize);  
  69.                 }  
  70.                 i++;  
  71.             }  
  72.             return raw;  
  73.         } catch (Exception e) {  
  74.             throw e;  
  75.         }  
  76.     }  
  77.   
  78.     /** 
  79.      * 根据privateKey 对data进行解密. 
  80.      *  
  81.      * @param privateKey 
  82.      * @param data 
  83.      * @throws Exception 
  84.      * @author Peter.Qiu 
  85.      */  
  86.     public static byte[] decryptMode(PrivateKey privateKey, byte[] data)  
  87.             throws Exception {  
  88.         Cipher cipher = Cipher.getInstance("RSA"new BouncyCastleProvider());  
  89.         cipher.init(Cipher.DECRYPT_MODE, privateKey);// DECRYPT_MODE 解密  
  90.         int blockSize = cipher.getBlockSize();  
  91.         ByteArrayOutputStream bout = new ByteArrayOutputStream(64);  
  92.         int j = 0;  
  93.   
  94.         while (data.length - j * blockSize > 0) {  
  95.             bout.write(cipher.doFinal(data, j * blockSize, blockSize));  
  96.             j++;  
  97.         }  
  98.         return bout.toByteArray();  
  99.     }  
  100.   
  101.     /** 
  102.      * 获取密钥. 
  103.      *  
  104.      * @param rsaKeyStore 
  105.      * @return 
  106.      * @throws Exception 
  107.      * @author Peter.Qiu 
  108.      */  
  109.     public static KeyPair getKeyPair(String rsaKeyStore) throws Exception {  
  110.         FileInputStream fis = new FileInputStream(rsaKeyStore);  
  111.         ObjectInputStream oos = new ObjectInputStream(fis);  
  112.         KeyPair kp = (KeyPair) oos.readObject();  
  113.         oos.close();  
  114.         fis.close();  
  115.         return kp;  
  116.     }  
  117.   
  118.     /** 
  119.      * 将密钥写入文件. 
  120.      *  
  121.      * @param kp 
  122.      * @param path 
  123.      * @throws Exception 
  124.      * @author Peter.Qiu 
  125.      */  
  126.     public static void saveKeyPair(KeyPair kp, String path) throws Exception {  
  127.         File file = new File(path);  
  128.         if (!file.exists() || file.isDirectory()) {  
  129.             file.createNewFile();  
  130.         }  
  131.         FileOutputStream fos = new FileOutputStream(path);  
  132.         ObjectOutputStream oos = new ObjectOutputStream(fos);  
  133.         // 生成密钥  
  134.         oos.writeObject(kp);  
  135.         oos.close();  
  136.         fos.close();  
  137.     }  
  138.   
  139.     /** 
  140.      * 用于生成公匙或私匙. 
  141.      *  
  142.      * @return 
  143.      * @throws NoSuchAlgorithmException 
  144.      * @author Peter.Qiu 
  145.      */  
  146.     public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {  
  147.   
  148.         SecureRandom sr = new SecureRandom();  
  149.         KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA",  
  150.                 new BouncyCastleProvider());  
  151.         // 注意密钥大小最好为1024,否则解密会有乱码情况.  
  152.         kg.initialize(1024, sr);  
  153.         KeyPair genKeyPair = kg.genKeyPair();  
  154.         return genKeyPair;  
  155.   
  156.     }  
  157.   
  158.     /** 
  159.      * 将公密或私密写入文件. 
  160.      *  
  161.      * @param obj 
  162.      * @param path 
  163.      * @throws Exception 
  164.      * @author Peter.Qiu 
  165.      */  
  166.     public static void saveFile(Object obj, String path) throws Exception {  
  167.         File file = new File(path);  
  168.         if (!file.exists() || file.isDirectory()) {  
  169.             file.createNewFile();  
  170.         }  
  171.         FileOutputStream fos = new FileOutputStream(path);  
  172.         ObjectOutputStream oos = new ObjectOutputStream(fos);  
  173.         // 生成密钥  
  174.         oos.writeObject(obj);  
  175.         oos.close();  
  176.         fos.close();  
  177.     }  
  178.   
  179.     /** 
  180.      * 获取公密. 
  181.      *  
  182.      * @param publicKeyPath 
  183.      * @return 
  184.      * @throws Exception 
  185.      * @author Peter.Qiu 
  186.      */  
  187.     public static PublicKey getPublicKey(String publicKeyPath) throws Exception {  
  188.         FileInputStream fis = new FileInputStream(publicKeyPath);  
  189.         ObjectInputStream oos = new ObjectInputStream(fis);  
  190.         PublicKey kp = (PublicKey) oos.readObject();  
  191.         oos.close();  
  192.         fis.close();  
  193.         return kp;  
  194.     }  
  195.   
  196.     /** 
  197.      * 获取私密. 
  198.      *  
  199.      * @param privateKeyPath 
  200.      * @return 
  201.      * @throws Exception 
  202.      * @author Peter.Qiu 
  203.      */  
  204.     public static PrivateKey getPrivateKey(String privateKeyPath)  
  205.             throws Exception {  
  206.         FileInputStream fis = new FileInputStream(privateKeyPath);  
  207.         ObjectInputStream oos = new ObjectInputStream(fis);  
  208.         PrivateKey kp = (PrivateKey) oos.readObject();  
  209.         oos.close();  
  210.         fis.close();  
  211.         return kp;  
  212.     }  
  213.   
  214.     public static void main(String[] args) throws Exception {  
  215.         File dir = new File("./key/");  
  216.         if (!dir.exists()) {  
  217.             dir.mkdir();  
  218.         }  
  219.         // 获取公匙及私匙  
  220.         KeyPair generateKeyPair = getKeyPair("./key/key");  
  221.   
  222.         // 生成公钥及私钥  
  223.         // generateKeyPair = generateKeyPair();  
  224.   
  225.         // 存储KeyPair到本地用于后期解密 注意修改前台RSAKeyPair  
  226.         // saveKeyPair(generateKeyPair,"./key/key");  
  227.   
  228.         System.out.println("generateKeyPair : " + generateKeyPair);  
  229.         // 公匙 用于前台加密  
  230.         PublicKey publicKey = null;// generateKeyPair.getPublic();  
  231.         publicKey = getPublicKey("./key/publicKey.key");  
  232.         System.out.println("publicKey:" + publicKey);  
  233.         // saveFile(publicKey,"./key/publicKey.key");  
  234.         // 私匙 存储在后台用于解密  
  235.         PrivateKey privateKey = null;// generateKeyPair.getPrivate(); //  
  236.         privateKey = getPrivateKey("./key/privateKey.key");//  
  237.         System.out.println("privateKey:" + privateKey);  
  238.         // saveFile(privateKey,"./key/privateKey.key");  
  239.   
  240.         // 测试加密解密  
  241.         String test = "saaaa";  
  242.         test = "Peter.Qiu丘丘丘邱";  
  243.         System.out.println("加密前字符:" + test);  
  244.         byte[] en_test = encryptMode(publicKey, test.getBytes("UTF-8"));  
  245.         System.out.println("加密后字符:" + new String(en_test));  
  246.   
  247.         byte[] de_test = decryptMode(privateKey, en_test);  
  248.         System.out.println("解密后字符:" + new String(de_test, "UTF-8"));  
  249.   
  250.     }  
  251.   
  252. }</span>  

0 0
原创粉丝点击