RSA 前段加密 java 后台解密 已调试通过

本人整理网上的。好多网上的调不通。在这里把调试好的贴出来。

1.   异步获取公钥(后台获取);你也可以将公钥串写在页面上;(接口看下面)

var publicKey = null;
$.ajax({ 
      url: ctx+"/userLogin.do?method=getRSAPublicKey", (请求地址)
      type: "post", 
     dataType: "text",
     async:false,
     success: function(data) { 
          if(data) publicKey = data; 
     } 
});

2. 前段页面加密写这个, 记得引入这个js  ( jsencrypt.min.js )

var encrypt = new JSEncrypt();
encrypt.setPublicKey(publicKey);   // 设置公钥
var password11 = encrypt.encrypt(password);     // 加密 password 是你页面获取的值   password11 是加密后的值  生成随机串

3. RSA  java工具类  我这里引入了 commons-codec 的依赖 1.4版本的

import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;


public class RSAUtils1 {
        public static final String CHARSET = "UTF-8";
        public static final String RSA_ALGORITHM = "RSA"; 
        private static final KeyPair keyPair = initKey(); 
        /** 
        * 初始化方法,产生key pair,提供provider和random 
        * @return KeyPair instance 
        */ 
       private static KeyPair initKey() { 
             try { 
                  //添加provider 
                 Provider provider = new org.bouncycastle.jce.provider.BouncyCastleProvider(); 
                 Security.addProvider(provider); 
                 //产生用于安全加密的随机数 
                 SecureRandom random = new SecureRandom(); 

                KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", provider); 
                generator.initialize(1024, random); 
                return generator.generateKeyPair(); 
          } catch(Exception e) { 
               throw new RuntimeException(e); 
          } 
     } 
      /** 
      * 产生public key 
      * @return public key字符串 
      */ 
      public static String generateBase64PublicKey() { 
           PublicKey publicKey = (RSAPublicKey)keyPair.getPublic(); 
           //encodeBase64(): Encodes binary data using the base64 
           //algorithm but does not chunk the output. 
           //getEncoded():返回key的原始编码形式 
           return new String(Base64.encodeBase64(publicKey.getEncoded()));
     } 
     /**
      * 产生private key
      * 
      * @return private key字符串 
      */
      public static String generateBase64PrivateKey(){
           PrivateKey privateKey = keyPair.getPrivate();
           return new String(Base64.encodeBase64(privateKey.getEncoded()));
     }
     /**
     * 私钥解密
     * @param data
     * @param privateKey
     * @return
     */
     public static String privateDecrypt(String data){
            try{
                  RSAPrivateKey privateKey = getPrivateKey(generateBase64PrivateKey());
                 Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
                 cipher.init(Cipher.DECRYPT_MODE, privateKey);
                 return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), privateKey.getModulus().bitLength()), CHARSET);
           }catch(Exception e){
                throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e);
          }
   }

    /**
     * 得到私钥
     * @param privateKey 密钥字符串(经过base64编码)
     * @throws Exception
    */
     public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
           //通过PKCS#8编码的Key指令获得私钥对象
           KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
           PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
           RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
           return key;
     }
      private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize){
            int maxBlock = 0;
            if(opmode == Cipher.DECRYPT_MODE){
                  maxBlock = keySize / 8;
            }else{
                  maxBlock = keySize / 8 - 11;
            }
          ByteArrayOutputStream out = new ByteArrayOutputStream();
          int offSet = 0;
          byte[] buff;
          int i = 0;
         try{
               while(datas.length > offSet){
                   if(datas.length-offSet > maxBlock){
                          buff = cipher.doFinal(datas, offSet, maxBlock);
                   }else{
                          buff = cipher.doFinal(datas, offSet, datas.length-offSet);
                   }
              out.write(buff, 0, buff.length);
              i++;
             offSet = i * maxBlock;
           }
       }catch(Exception e){
               throw new RuntimeException("加解密阀值为["+maxBlock+"]的数据时发生异常", e);
      }
         byte[] resultDatas = out.toByteArray();
         IOUtils.closeQuietly(out);
          return resultDatas;
    }

       public static void main(String[] args) {
            // 获得公钥 私钥对 
             System.out.println("公钥:"+generateBase64PublicKey());
            System.out.println("秘钥:"+generateBase64PrivateKey());
          }
    }

4. 给前台返回公钥 (文章第1步调用接口)

@RequestMapping(params = "method=getRSAPublicKey")
       public void getRSAPublicKey(HttpServletRequest request,HttpServletResponse response){
             PrintWriter writer;
               try {
                     writer = response.getWriter();
                     String publicKey = RSAUtils1.generateBase64PublicKey();
                      writer.write(publicKey); 
              } catch (IOException e) {
                       // TODO Auto-generated catch block
                        e.printStackTrace();
              } 
        }

5.解密 (解密的方法

 //先对前端密码进行RSA解密 加到接收加密的方法中
        password = password.replace(" ","+");  加密的数据放在Url传递时,会将“+”变成空格,这里变回来。
        System.out.println("解密前:"+password);
         password = RSAUtils1.privateDecrypt(password);
         System.out.println("解密后密码:"+password);

结束。谢谢交流评论。

 

posted @ 2018-06-25 16:53  m5n7xiao  阅读(1340)  评论(1编辑  收藏  举报