zoukankan      html  css  js  c++  java
  • RSA加密&解密【Java&Scala】

    一.简介

      RSA加密算法是一种非对称加密算法。在公开密钥加密电子商业中RSA被广泛使用。

      RSA公开密钥密码体制。所谓公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。

      在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,由于无法计算出大数n的欧拉函数phi(N),所以不能根据PK计算出SK。

      RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA是被研究得最广泛的公钥算法,从提出到现今的三十多年里,经历了各种攻击的考验,逐渐为人们接受,截止2017年被普遍认为是最优秀的公钥方案之一。 

    二.代码实现【Java版】

      1 package cn.ai;
      2 
      3 import java.io.UnsupportedEncodingException;
      4 import java.security.InvalidKeyException;
      5 import java.security.KeyFactory;
      6 import java.security.KeyPair;
      7 import java.security.KeyPairGenerator;
      8 import java.security.NoSuchAlgorithmException;
      9 import java.security.SecureRandom;
     10 import java.security.interfaces.RSAPrivateKey;
     11 import java.security.interfaces.RSAPublicKey;
     12 import java.security.spec.InvalidKeySpecException;
     13 import java.security.spec.PKCS8EncodedKeySpec;
     14 import java.security.spec.X509EncodedKeySpec;
     15 import java.util.HashMap;
     16 import java.util.Map;
     17 
     18 import javax.crypto.BadPaddingException;
     19 import javax.crypto.Cipher;
     20 import javax.crypto.IllegalBlockSizeException;
     21 import javax.crypto.NoSuchPaddingException;
     22 
     23 import org.apache.commons.codec.binary.Base64;
     24 
     25 public class RSACrypt {
     26 
     27     private static Map<Integer, String> keyMap = new HashMap<Integer, String>();
     28     
     29     /**
     30      * 初始化生成公钥和私钥
     31      * @throws NoSuchAlgorithmException 
     32      */
     33     public static void init() throws NoSuchAlgorithmException{
     34         /**
     35          * KeyPairGenerator用于生成公钥和私钥对,基于RSA算法生成对象
     36          */
     37         KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
     38         /**
     39          * 初始化秘钥对生成器,秘钥大小为1024位
     40          */
     41         keyPairGen.initialize(1024, new SecureRandom());
     42         /**
     43          * 生成秘钥
     44          */
     45         KeyPair keyPair = keyPairGen.generateKeyPair();
     46         /**
     47          * 获取私钥
     48          */
     49         RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();
     50         String privateKeyStr = new String(Base64.encodeBase64(privateKey.getEncoded()));
     51         /**    
     52          * 获取公钥
     53          */
     54         RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
     55         String publicKeyStr = new String(Base64.encodeBase64(publicKey.getEncoded()));
     56         
     57         /**
     58          * 保存公钥,私钥
     59          */
     60         keyMap.put(0, publicKeyStr); // 公钥
     61         keyMap.put(1, privateKeyStr);// 私钥
     62     }
     63     
     64     /**
     65      * 公钥加密
     66      * @throws NoSuchAlgorithmException 
     67      * @throws InvalidKeySpecException 
     68      * @throws Exception 
     69      */
     70     public static String rsaEncrypt(String content, String publicKey) throws InvalidKeySpecException, NoSuchAlgorithmException, Exception{
     71         //base64编码的公钥
     72         byte[] encoded = Base64.decodeBase64(publicKey);
     73         RSAPublicKey rsaPublicKey = (RSAPublicKey)KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(encoded));
     74         // RSA加密
     75         Cipher cipher = Cipher.getInstance("RSA");
     76         cipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey);
     77         
     78         String outPublicKey = Base64.encodeBase64String(cipher.doFinal(content.getBytes("UTF-8")));
     79         
     80         return outPublicKey;
     81     }
     82     
     83     /**
     84      * 私钥解密
     85      * @throws UnsupportedEncodingException 
     86      * @throws NoSuchAlgorithmException 
     87      * @throws InvalidKeySpecException 
     88      * @throws NoSuchPaddingException 
     89      * @throws InvalidKeyException 
     90      * @throws BadPaddingException 
     91      * @throws IllegalBlockSizeException 
     92      * @throws Exception
     93      */
     94     public static String rsaDecrypt(String content, String privateKey) throws UnsupportedEncodingException, InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
     95         //base64位解码加密后的字符串
     96         byte[] inputByte = Base64.decodeBase64(content.getBytes("UTF-8"));
     97         //base64编码的私钥
     98         byte[] decoded = Base64.decodeBase64(privateKey);
     99         RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
    100         //RSA解密
    101         Cipher cipher = Cipher.getInstance("RSA");
    102         cipher.init(Cipher.DECRYPT_MODE, rsaPrivateKey);
    103         String outPrivateKey = new String(cipher.doFinal(inputByte));
    104         return outPrivateKey;
    105     }
    106     
    107     public static void main(String[] args) throws Exception {
    108         /**
    109          * 初始化生成公钥,私钥
    110          */
    111         init();
    112         /**
    113          * 加密数据
    114          */
    115         String message = "abc123";
    116         System.out.println("随机生成的公钥为:" + keyMap.get(0));
    117         System.out.println("随机生成的私钥为:" + keyMap.get(1));
    118 
    119         System.out.println("加密前的数据:" + message);
    120         String messageEncrypt = rsaEncrypt(message, keyMap.get(0));
    121         System.out.println("加密后的数据:" + messageEncrypt);
    122         
    123         //String mid = "MIIc" + keyMap.get(1).substring(4, keyMap.get(1).length());
    124         //System.out.println("随机生成的私钥为:" + mid);
    125         String messageDecrypt = rsaDecrypt(messageEncrypt, keyMap.get(1));
    126         System.out.println("解密后的数据:" + messageDecrypt);
    127     }
    128 
    129 }

    三.结果【Java版】

    1 随机生成的公钥为:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzveY+Gdrm4gY2IGT+M1yESXHPLSS7Nq/iex4h2oI3x0kSvYOoepQSPUhZvnUJEsrnYHKI9CZPJXNchqQFdR2Zy70GX/58yA700PVpk278z32aZ4OFkqhrmtULRiwF/ILpjucr7dIrgOU+hFTKHHc0fqhtHVWZVYcf1ZyKP8fQBwIDAQAB
    2 随机生成的私钥为:MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALO95j4Z2ubiBjYgZP4zXIRJcc8tJLs2r+J7HiHagjfHSRK9g6h6lBI9SFm+dQkSyudgcoj0Jk8lc1yGpAV1HZnLvQZf/nzIDvTQ9WmTbvzPfZpng4WSqGua1QtGLAX8gumO5yvt0iuA5T6EVMocdzR+qG0dVZlVhx/VnIo/x9AHAgMBAAECgYAV9yoRAsXem1aY/MJ60joHLJaM8/5eJqO98L/Q8UwilucWNDTHvRslU3npBb51umczeXTlybh4yaHcd9PJmvNf6LI0LsCAWEqW6Y4/1kX2ro8w/a5uLLZMECa9q0xkn0+QWMMrcHxzUVhlott5lDx9ejiW+a3KpNscQLSxgZSeAQJBAN2N45wUFSvcGFZAOwHL6YpCIrECokdhFFp+eABPYJb+rDFfFyiiK8THk/osD2l0Tqtdl+mPJEAbXU1aK0VdnQECQQDPr9OwC0rpvttzq6TiEJ4S1Dz3kZwS2NkrukbgqWkGpC7HggBjYYyrujoEpEnPvqnm6oTWCDqh+YRWC6RMp4UHAkAJCwiWT0+J6cLoilieOyd+KDLoTLY4+aJuCyl0wcisgRqgLURxuSTWNFs649+BK2kmn3xa4SfWogdN5/dKLocBAkACeZjvNyM8Z97boQcE/qezl73mQWD3xIfKAp1Hnh03TAuWqxDwHkB752s7lO2gQShrLQ5KMqzoMz4FfHwHwdNPAkEAtNG3NONm0f4McwEYyxXkrlLWisf67xkTo6rLfxnf7f+xk8W6u6kf339AZlfOUv5I1BZKfka3hUxaXlpsYmQ0Xg==
    3 加密前的数据:abc123
    4 加密后的数据:s4P8ihNvDHdqB3libM2lj8eC37TQK/UBrUIKM4If42oMYiCVo/4q07FPLfDYCBMEa9sbdDSFA1mcXiWRvwIH+658Nu+dLSe1SQfuwI+7q0KbP0lQeCh3SkBvTqAt0BmEnpDvSUzn1FH/W8Wlqet9IBsTU7mZioXZ9jCSTvKvU8w=
    5 解密后的数据:abc123

    四.代码实现【Scala版】

     1 package big.data.analyse.encryption
     2 
     3 import java.security.spec.{PKCS8EncodedKeySpec, X509EncodedKeySpec}
     4 import java.security.{KeyFactory, SecureRandom, KeyPairGenerator}
     5 import javax.crypto.Cipher
     6 
     7 import org.apache.commons.codec.binary.Base64
     8 
     9 /**
    10   * Created by zhen on 2019/6/15.
    11   */
    12 object RSA {
    13   var keyMap : Map[Int, String] = Map()
    14 
    15   /**
    16     * 初始化公钥,私钥
    17     */
    18   def init(): Unit ={
    19     val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
    20     keyPairGenerator.initialize(1024, new SecureRandom())
    21     val keyPair = keyPairGenerator.generateKeyPair()
    22     val privateKey = keyPair.getPrivate
    23     val privateKeyStr = new String(Base64.encodeBase64(privateKey.getEncoded))
    24 
    25     val publicKey = keyPair.getPublic
    26     val publicKeyStr = new String(Base64.encodeBase64(publicKey.getEncoded))
    27 
    28     keyMap += (0 -> publicKeyStr) // 0表示公钥
    29     keyMap += (1 -> privateKeyStr) // 1表示私钥
    30   }
    31 
    32   /**
    33     * 公钥加密
    34     */
    35   def rsaEncrypt(content : String, publicKey : String): String ={
    36     val encoded = Base64.decodeBase64(publicKey)
    37     val rsaPublicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(encoded))
    38 
    39     val cipher = Cipher.getInstance("RSA")
    40     cipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey)
    41 
    42     val enContent = Base64.encodeBase64String(cipher.doFinal(content.getBytes("UTF-8")))
    43 
    44     return enContent
    45   }
    46 
    47   /**
    48     * 私钥解密
    49     */
    50   def rsaDecrypt(content : String, privateKey : String): String ={
    51     val bytes = Base64.decodeBase64(content.getBytes("UTF-8"))
    52     val decoded = Base64.decodeBase64(privateKey)
    53     val rsaPrivateKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded))
    54 
    55     val cipher = Cipher.getInstance("RSA")
    56     cipher.init(Cipher.DECRYPT_MODE, rsaPrivateKey)
    57 
    58     val deContent = new String(cipher.doFinal(bytes))
    59 
    60     return deContent
    61   }
    62 
    63   /**
    64     * 测试
    65     * @param args
    66     */
    67   def main(args: Array[String]) {
    68 
    69     /**
    70       * 初始化加密算法
    71       */
    72     init()
    73     println("公钥:" +keyMap.get(0).get+ "
    私钥:" + keyMap.get(1).get)
    74 
    75     /**
    76       * 加密内容
    77       */
    78     val content = "abc123"
    79     println("加密前的数据:" + content)
    80 
    81     /**
    82       * 加密
    83       */
    84     val enContent = rsaEncrypt(content, keyMap.get(0).get)
    85     println("加密后的数据:" + enContent)
    86 
    87     /**
    88       * 解密
    89       */
    90     val deContent = rsaDecrypt(enContent, keyMap.get(1).get)
    91     println("解密后的数据:" + deContent)
    92   }
    93 }

     五.结果【Scala版】

    1 公钥:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpWv6go/JB6/fgkFobB8UNG9yGEPEdJnRxy26YISXb2ACRvC1BZ4bKECdnVk5EMwEyIxtfYLbvf0PjVq1CYAimYd6D97teWSQM0ZsdYYzUeSz+KJABugt4A4LNitnfmn1jOToSdjlXZIlrzKQtNxXi4fEFHqg5CMUgrbU40amrcQIDAQAB
    2 私钥:MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAKla/qCj8kHr9+CQWhsHxQ0b3IYQ8R0mdHHLbpghJdvYAJG8LUFnhsoQJ2dWTkQzATIjG19gtu9/Q+NWrUJgCKZh3oP3u15ZJAzRmx1hjNR5LP4okAG6C3gDgs2K2d+afWM5OhJ2OVdkiWvMpC03FeLh8QUeqDkIxSCttTjRqatxAgMBAAECgYAOIpgqFET+F5Hi3mmG5AkgZPjs/7EAO9twPAiJDgs45Dh38XrdgKSRbPO8/kkeDBvHcYKxXUMnjjm+WdewOI/AIJfhRD4dSW7vLEhDAD/sWN2gop34uFLIwFI4XESvdlObqFU082HqsiC6qP4b2/W5S5JDSx2kQaRLppl1/wX6mQJBANdhmlp2S3aHalKqdViTyLmwqDmQQQDCrdLUs0BCJIJBaRWiN5EbLeCF4EtbCN8Pe6KtiV1R1ZnAlvm7dVlCldMCQQDJS09ybefxe/CApr6ppK7bwSf2vVOqDO2dBm46oapK6otpSSt1USvah0yGNenu7hoPFFyFe3vlrbV3dQJBFdsrAkEAv67Xxma9ZnHCCGw4H2r3G3vDW+esUlbwiFBQb4HuKBa6xUwnk/bSb532LlqInKyU5gT32Zu5NCsYso1JNPVzjQJBAJNruWKnxW/hAlFmTUq21m0Q+HDHVce7siYHOKFuFubJAZL5SH+iFAj2f//m6k3XSXRzyBLmTeX3I2i6ZA1AsYMCQQCXnuh0VjBTqSrvrEWXlnyiQ1cpQdmAhI6YlnKW3Mcd6jjekCjAG7CXU1N845Ax7btTlF1Ca+vwcaVzm0oF80mQ
    3 加密前的数据:abc123
    4 加密后的数据:jcSjLubNx/1Vk4FEWBwukb8FK3w/QMNZ6UY5lZxLuMxvQ+sl/9cndIh5wNRkzowxmxDQnNcMlUQ5qwIvKnExSVXfBuoRKBH7J+9q7yb1XQR+m+r53djTrNbV15wztHO7KDh4bhlUSbv217OkTdBMb8Exh4aKuih7cUdsD9XQ+60=
    5 解密后的数据:abc123
  • 相关阅读:
    mac上的终端bash命令(二)基础
    Android 开发笔记___drawable
    Android 开发笔记___图像按钮__imageButton
    Android 开发笔记___滚动视图__scroll view
    Android 开发笔记___textvieww__跑马灯效果
    Android 开发笔记___textview_聊天室效果
    Android 开发笔记___图像视图__简单截屏
    Android 开发笔记___图像视图
    javaScript学习笔记(一)js基础
    iview2+ 表单密码验证
  • 原文地址:https://www.cnblogs.com/yszd/p/11006039.html
Copyright © 2011-2022 走看看