JavaWeb RSA加密使用小解

来源:互联网 发布:淘宝怎么能分期付款 编辑:程序博客网 时间:2024/06/01 23:48

1. RSA密文和密钥

不管明文长度是多少,RSA 生成的密文长度总是固定的。
但是明文长度不能超过密钥长度。比如 Java 默认的 RSA 加密实现不允许明文长度超过密钥长度减去 11(单位是字节,也就是 byte)。也就是说,如果我们定义的密钥(我们可以通过 java.security.KeyPairGenerator.initialize(int keysize) 来定义密钥长度)长度为 1024(单位是位,也就是 bit),生成的密钥长度就是 1024位 / 8位/字节 = 128字节,那么我们需要加密的明文长度不能超过 128字节 -
11 字节 = 117字节。也就是说,我们最大能将 117 字节长度的明文进行加密,否则会出问题(抛诸如 javax.crypto.IllegalBlockSizeException:Data must not be longer than 53 bytes 的异常)。

2. Java端

String modulus = publicKey.getModulus().toString(16);

String pubexp =publicKey.getPublicExponent().toString(16);

String priexp =privateKey.getPrivateExponent().toString(16);

注意需要使用16进制下发到客户端

package com.inphase.demo.utils;

 

import java.math.BigInteger;

import java.security.KeyFactory;

import java.security.KeyPair;

import java.security.KeyPairGenerator;

importjava.security.NoSuchAlgorithmException;

import java.security.Security;

importjava.security.interfaces.RSAPrivateKey;

importjava.security.interfaces.RSAPublicKey;

import java.security.spec.RSAPrivateKeySpec;

import java.security.spec.RSAPublicKeySpec;

import java.util.HashMap;

 

import javax.crypto.Cipher;

 

importorg.bouncycastle.jce.provider.BouncyCastleProvider;

 

public class RSAUtils {

        /**

    * 加密算法RSA

    */

    publicstatic final String KEY_ALGORITHM = "RSA";

    

   /**

    * 签名算法

    */

   public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

       /**

        * 生成公钥和私钥

        *

        * @throws NoSuchAlgorithmException

        *

        */

       publicstatic HashMap<String, Object> getKeys()

                     throwsNoSuchAlgorithmException {

              Security.addProvider(newBouncyCastleProvider());

              HashMap<String,Object> map = new HashMap<String, Object>();

              KeyPairGeneratorkeyPairGen = KeyPairGenerator.getInstance("RSA",

                            newBouncyCastleProvider());

              keyPairGen.initialize(1024);

              KeyPairkeyPair = keyPairGen.generateKeyPair();

              RSAPublicKeypublicKey = (RSAPublicKey) keyPair.getPublic();

              RSAPrivateKeyprivateKey = (RSAPrivateKey) keyPair.getPrivate();

              map.put("public",publicKey);

              map.put("private",privateKey);

              returnmap;

       }

 

       /**

        * 使用模和指数生成RSA公钥

        *

        * @param modulus

        *           模

        * @param exponent

        *           指数

        * @return

        */

       publicstatic RSAPublicKey getPublicKey(String modulus, String exponent) {

              Security.addProvider(newBouncyCastleProvider());

              try{

                     BigIntegerb1 = new BigInteger(modulus);

                     BigIntegerb2 = new BigInteger(exponent);

                     KeyFactorykeyFactory = KeyFactory.getInstance("RSA",

                                   newBouncyCastleProvider());

                     RSAPublicKeySpeckeySpec = new RSAPublicKeySpec(b1, b2);

                     return(RSAPublicKey) keyFactory.generatePublic(keySpec);

              }catch (Exception e) {

                     e.printStackTrace();

                     returnnull;

              }

       }

 

       /**

        * 使用模和指数生成RSA私钥 /None/NoPadding

        *

        * @param modulus

        *           模

        * @param exponent

        *           指数

        * @return

        */

       publicstatic RSAPrivateKey getPrivateKey(String modulus, String exponent) {

              try{

                     Security.addProvider(newBouncyCastleProvider());

                     BigIntegerb1 = new BigInteger(modulus);

                     BigInteger b2 = new BigInteger(exponent);

                     KeyFactorykeyFactory = KeyFactory.getInstance("RSA",

                                   newBouncyCastleProvider());

                     RSAPrivateKeySpeckeySpec = new RSAPrivateKeySpec(b1, b2);

                     return(RSAPrivateKey) keyFactory.generatePrivate(keySpec);

              }catch (Exception e) {

                     e.printStackTrace();

                     returnnull;

              }

       }

 

       /**

        * 公钥加密

        *

        * @param data

        * @param publicKey

        * @return

        * @throws Exception

        */

       publicstatic String encryptByPublicKey(String data, RSAPublicKey publicKey)

                     throwsException {

              Security.addProvider(newBouncyCastleProvider());

              Ciphercipher = Cipher.getInstance("RSA", new BouncyCastleProvider());

              cipher.init(Cipher.ENCRYPT_MODE,publicKey);

              //模长

              intkey_len = publicKey.getModulus().bitLength() / 8;

              // 加密数据长度 <= 模长-11

              String[]datas = splitString(data, key_len - 11);

              Stringmi = "";

              //如果明文长度大于模长-11则要分组加密

              for(String s : datas) {

                     mi+= bcd2Str(cipher.doFinal(s.getBytes()));

              }

              returnmi;

       }

 

       /**

        * 私钥解密

        *

        * @param data

        * @param privateKey

        * @return

        * @throws Exception

        */

       publicstatic String decryptByPrivateKey(String data,

                     RSAPrivateKeyprivateKey) throws Exception {

              Security.addProvider(newBouncyCastleProvider());

              Ciphercipher = Cipher.getInstance("RSA", new BouncyCastleProvider());

              cipher.init(Cipher.DECRYPT_MODE,privateKey);

              //模长

              intkey_len = privateKey.getModulus().bitLength() / 8;

              byte[]bytes = data.getBytes();

              byte[]bcd = ASCII_To_BCD(bytes, bytes.length);

              //System.err.println(bcd.length);

              //如果密文长度大于模长则要分组解密

              Stringming = "";

              byte[][]arrays = splitArray(bcd, key_len);

              try{

                     for(byte[] arr : arrays) {

                            ming+= new String(cipher.doFinal(arr));

                     }

              }catch (Exception e) {

                     e.printStackTrace();

              }

             

              returnming;

       }

       /**

        * ASCII码转BCD码

        *

        */

       publicstatic byte[] ASCII_To_BCD(byte[] ascii, int asc_len) {

              byte[]bcd = new byte[asc_len / 2];

              intj = 0;

              for(int i = 0; i < (asc_len + 1) / 2; i++) {

                     bcd[i]= asc_to_bcd(ascii[j++]);

                     bcd[i]= (byte) (((j >= asc_len) ? 0x00 : asc_to_bcd(ascii[j++])) + (bcd[i]<< 4));

              }

              returnbcd;

       }

 

       publicstatic byte asc_to_bcd(byte asc) {

              bytebcd;

 

              if((asc >= '0') && (asc <= '9'))

                     bcd= (byte) (asc - '0');

              elseif ((asc >= 'A') && (asc <= 'F'))

                     bcd= (byte) (asc - 'A' + 10);

              elseif ((asc >= 'a') && (asc <= 'f'))

                     bcd= (byte) (asc - 'a' + 10);

              else

                     bcd= (byte) (asc - 48);

              returnbcd;

       }

 

       /**

        * BCD转字符串

        */

       publicstatic String bcd2Str(byte[] bytes) {

              chartemp[] = new char[bytes.length * 2], val;

 

              for(int i = 0; i < bytes.length; i++) {

                     val= (char) (((bytes[i] & 0xf0) >> 4) & 0x0f);

                     temp[i* 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0');

 

                     val= (char) (bytes[i] & 0x0f);

                     temp[i* 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0');

              }

              returnnew String(temp);

       }

 

       /**

        * 拆分字符串

        */

       publicstatic String[] splitString(String string, int len) {

              intx = string.length() / len;

              inty = string.length() % len;

              intz = 0;

              if(y != 0) {

                     z= 1;

              }

              String[]strings = new String[x + z];

              Stringstr = "";

              for(int i = 0; i < x + z; i++) {

                     if(i == x + z - 1 && y != 0) {

                            str= string.substring(i * len, i * len + y);

                     }else {

                            str= string.substring(i * len, i * len + len);

                     }

                     strings[i] = str;

              }

              returnstrings;

       }

 

       /**

        * 拆分数组

        */

       publicstatic byte[][] splitArray(byte[] data, int len) {

              intx = data.length / len;

              inty = data.length % len;

              intz = 0;

              if(y != 0) {

                     z= 1;

              }

              byte[][]arrays = new byte[x + z][];

              byte[]arr;

              for(int i = 0; i < x + z; i++) {

                     arr= new byte[len];

                     if(i == x + z - 1 && y != 0) {

                            System.arraycopy(data,i * len, arr, 0, y);

                     }else {

                            System.arraycopy(data,i * len, arr, 0, len);

                     }

                     arrays[i]= arr;

              }

              returnarrays;

       }

}

需要引入jar

3. jsp页面

<scripttype="text/javascript" src="<%=basePath%>js/jquery.min.js"></script>

    <script type="text/javascript"src="<%=basePath%>js/BigInt.js"></script>

    <script type="text/javascript"src="<%=basePath%>js/Barrett.js"></script>

     <script type="text/javascript"src="<%=basePath%>js/RSA.js"></script>

 

 

var key =RSAUtils.getKeyPair(publicexp,privateexp,moudel);

         axes = axes.split("").reverse().join("");

returnRSAUtils.encryptedString(key,data);

 

0 0