RSA 前段加密 java 後臺解密 已調試經過

本人整理網上的。好多網上的調不通。在這裏把調試好的貼出來。前端

1.   異步獲取公鑰(後臺獲取);你也能夠將公鑰串寫在頁面上;java

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

2. 前段加密 引入這個  jsencrypt.min.js  apache

var encrypt = new JSEncrypt();
encrypt.setPublicKey(publicKey);   // 設置公鑰
var password11 = encrypt.encrypt(password);     // 加密 password 是你頁面獲取的值   password11 是加密後的值  生成隨機串安全

3. RSA 工具類  我這裏引入了 commons-codec 的依賴 1.4版本的app

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;dom

import javax.crypto.Cipher;異步

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


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());
          }
    }ide

4. 給前臺返回公鑰

       @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);

 

結束。謝謝交流評論。

相關文章
相關標籤/搜索