RSA加密解密算法java实现

来源:互联网 发布:lte网络优化工程师招聘 编辑:程序博客网 时间:2024/06/04 07:45

转载自:http://blog.csdn.net/markcooper/article/details/53814747


pom.xml:

[html] view plain copy
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  3.   <modelVersion>4.0.0</modelVersion>  
  4.   
  5.   <groupId>com.dzh</groupId>  
  6.   <artifactId>encrypt-util</artifactId>  
  7.   <version>0.0.1-SNAPSHOT</version>  
  8.   <packaging>jar</packaging>  
  9.   
  10.   <name>encrypt-util</name>  
  11.   <url>http://maven.apache.org</url>  
  12.   
  13.   <properties>  
  14.     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
  15.   </properties>  
  16.   
  17.   <dependencies>  
  18.     <dependency>  
  19.         <groupId>commons-codec</groupId>  
  20.         <artifactId>commons-codec</artifactId>  
  21.         <version>1.9</version>  
  22.     </dependency>  
  23.     <dependency>  
  24.         <groupId>org.bouncycastle</groupId>  
  25.         <artifactId>bcprov-jdk15on</artifactId>  
  26.         <version>1.55</version>  
  27. <!--         <scope>provided</scope> -->  
  28.     </dependency>  
  29.   </dependencies>  
  30. </project>  

关于下面的代码的注意点:

此工具类能使用指定的字符串,每次生成相同的公钥和私钥且在linux和windows密钥也相同;相同的原文和密钥生成的密文相同。

如果需要每次生成不同的密钥或者生成不同的密文,代码要做修改。

下面的代码用到了我写的BASE64加密,参考《加密解密算法java实现(1)—BASE64》

java代码如下:

[java] view plain copy
  1. package com.dzh.rsa;  
  2.   
  3. import java.security.Key;  
  4. import java.security.KeyFactory;  
  5. import java.security.KeyPair;  
  6. import java.security.KeyPairGenerator;  
  7. import java.security.SecureRandom;  
  8. import java.security.interfaces.RSAPrivateKey;  
  9. import java.security.interfaces.RSAPublicKey;  
  10. import java.security.spec.PKCS8EncodedKeySpec;  
  11. import java.security.spec.X509EncodedKeySpec;  
  12. import java.util.HashMap;  
  13. import java.util.Map;  
  14.   
  15. import javax.crypto.Cipher;  
  16.   
  17. import org.bouncycastle.jce.provider.BouncyCastleProvider;  
  18.   
  19. import com.dzh.base64.BASE64Util;  
  20.   
  21. /** 
  22.  * RSA加密解密 
  23.  * 此工具类能使用指定的字符串,每次生成相同的公钥和私钥且在linux和windows密钥也相同;相同的原文和密钥生成的密文相同 
  24.  */  
  25. public class RSAUtil {  
  26.     private static final String ALGORITHM_RSA = "RSA";  
  27.     private static final String ALGORITHM_SHA1PRNG = "SHA1PRNG";  
  28.     private static final int KEY_SIZE = 1024;  
  29.     private static final String PUBLIC_KEY = "RSAPublicKey";  
  30.     private static final String PRIVATE_KEY = "RSAPrivateKey";  
  31.     private static final String TRANSFORMATION = "RSA/None/NoPadding";  
  32.       
  33.     /** 
  34.      * 解密 
  35.      * 用私钥解密,解密字符串,返回字符串 
  36.      * @param data 
  37.      * @param key 
  38.      * @return 
  39.      * @throws Exception 
  40.      */  
  41.     public static String decryptByPrivateKey(String data, String key) throws Exception {  
  42.         return new String(decryptByPrivateKey(BASE64Util.decodeToByte(data), key));  
  43.     }  
  44.       
  45.     /** 
  46.      * 加密 
  47.      * 用公钥加密,加密字符串,返回用base64加密后的字符串 
  48.      * @param data 
  49.      * @param key 
  50.      * @return 
  51.      * @throws Exception 
  52.      */  
  53.     public static String encryptByPublicKey(String data, String key) throws Exception {  
  54.         return encryptByBytePublicKey(data.getBytes(), key);  
  55.     }  
  56.     /** 
  57.      * 加密 
  58.      * 用公钥加密,加密byte数组,返回用base64加密后的字符串 
  59.      * @param data 
  60.      * @param key 
  61.      * @return 
  62.      * @throws Exception 
  63.      */  
  64.     public static String encryptByBytePublicKey(byte[] data, String key) throws Exception {  
  65.         return BASE64Util.encodeByte(encryptByPublicKey(data, key));  
  66.     }  
  67.       
  68.     /** 
  69.      * 解密 
  70.      * 用私钥解密 
  71.      * @param data 
  72.      * @param key 
  73.      * @return 
  74.      * @throws Exception 
  75.      */  
  76.     public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {  
  77.         byte[] keyBytes = BASE64Util.decodeToByte(key);//对私钥解密  
  78.         /*取得私钥*/  
  79.         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);  
  80.         KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);  
  81.         Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);  
  82.         /*对数据解密*/  
  83.         Cipher cipher = Cipher.getInstance(TRANSFORMATION, new BouncyCastleProvider());//相同的原文、公钥能生成相同的密文。如果使用Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());//相同的原文、公钥生成的密文不同  
  84.         cipher.init(Cipher.DECRYPT_MODE, privateKey);  
  85.           
  86.         return cipher.doFinal(data);  
  87.     }  
  88.       
  89.     /** 
  90.      * 加密 
  91.      * 用公钥加密 
  92.      * @param data 
  93.      * @param key 
  94.      * @return 
  95.      * @throws Exception 
  96.      */  
  97.     public static byte[] encryptByPublicKey(byte[] data, String key) throws Exception {  
  98.         byte[] keyBytes = BASE64Util.decodeToByte(key);//对公钥解密  
  99.         /*取得公钥*/  
  100.         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);  
  101.         KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);  
  102.         Key publicKey = keyFactory.generatePublic(x509KeySpec);  
  103.         /*对数据加密*/  
  104.         Cipher cipher = Cipher.getInstance(TRANSFORMATION, new BouncyCastleProvider());//相同的原文、公钥能生成相同的密文。如果使用Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());//相同的原文、公钥生成的密文不同  
  105.         cipher.init(Cipher.ENCRYPT_MODE, publicKey);  
  106.           
  107.         return cipher.doFinal(data);  
  108.     }  
  109.       
  110.     /** 
  111.      * 取得私钥 
  112.      * @param keyMap 
  113.      * @return 
  114.      */  
  115.     public static String getPrivateKey(Map<String, Object> keyMap) {  
  116.         Key key = (Key) keyMap.get(PRIVATE_KEY);  
  117.         return BASE64Util.encodeByte(key.getEncoded());  
  118.     }  
  119.       
  120.     /** 
  121.      * 取得公钥 
  122.      * @param keyMap 
  123.      * @return 
  124.      */  
  125.     public static String getPublicKey(Map<String, Object> keyMap) {  
  126.         Key key = (Key) keyMap.get(PUBLIC_KEY);  
  127.         return BASE64Util.encodeByte(key.getEncoded());  
  128.     }  
  129.       
  130.     /** 
  131.      * 初始化公钥和私钥 
  132.      * @param seed 
  133.      * @return 
  134.      * @throws Exception 
  135.      */  
  136.     public static Map<String, Object> initKey(String seed) throws Exception {  
  137.         KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(ALGORITHM_RSA);  
  138.         SecureRandom random = SecureRandom.getInstance(ALGORITHM_SHA1PRNG);//如果使用SecureRandom random = new SecureRandom();//windows和linux默认不同,导致两个平台生成的公钥和私钥不同  
  139.         random.setSeed(seed.getBytes());//使用种子则生成相同的公钥和私钥  
  140.         keyPairGen.initialize(KEY_SIZE, random);  
  141.         KeyPair keyPair = keyPairGen.generateKeyPair();  
  142.           
  143.         RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();//公钥  
  144.         RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();//私钥  
  145.           
  146.         Map<String, Object> keyMap = new HashMap<String, Object>(2);  
  147.           
  148.         keyMap.put(PUBLIC_KEY, publicKey);  
  149.         keyMap.put(PRIVATE_KEY, privateKey);  
  150.         return keyMap;  
  151.     }  
  152.       
  153.     /** 
  154.      * 使用示例 
  155.      * @param args 
  156.      * @throws Exception 
  157.      */  
  158.     public static void main(String[] args) throws Exception {  
  159.         String source = "12dfefDKLJKLKL464d中文f465as43f1a3 f46e353D1F34&*^$E65F46EF43456abcd54as56f00ef";//原文  
  160.         String seed = "abc123";//种子  
  161.           
  162.         System.out.println("原文:\n" + source);  
  163.         Map<String, Object> keyMap = RSAUtil.initKey(seed);//初始化密钥  
  164.         String publicKey = RSAUtil.getPublicKey(keyMap);//公钥  
  165.         String privateKey = RSAUtil.getPrivateKey(keyMap);//私钥  
  166.         System.out.println("公钥:\n" + publicKey);  
  167.         System.out.println("私钥:\n" + privateKey);  
  168.         String encodedStr = RSAUtil.encryptByPublicKey(source, publicKey);//加密  
  169.         System.out.println("密文:\n" + encodedStr);  
  170.         String decodedStr = RSAUtil.decryptByPrivateKey(encodedStr, privateKey);//解密  
  171.         System.out.println("解密后的结果:\n" + decodedStr);  
  172.     }  
  173. }