RSA 加密-重写base64 适用于反射

来源:互联网 发布:c# socket接收数据 编辑:程序博客网 时间:2024/06/07 12:31
package com.pingan.haofang.connector.common.secretutil;import java.io.ByteArrayOutputStream;import java.security.Key;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.PrivateKey;import java.security.PublicKey;import java.security.Signature;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.HashMap;import java.util.Map;import javax.crypto.Cipher;/** * @Title: RSAUtil不对称加解密工具类 * @Description: 处理数据传输加密问题 * @Team: 新金融业务研发团队 * @Author wangcs * @Date 2017年05月27日 * @Version V1.0 */public class RSAUtils {    /**      * 加密算法RSA     */    public static final String KEY_ALGORITHM = "RSA";        /**      * 签名算法     */    public static final String SIGNATURE_ALGORITHM = "MD5withRSA";    /**      * 获取公钥的key     */    private static final String PUBLIC_KEY = "RSAPingAnKey1";        /**      * 获取私钥的key     */    private static final String PRIVATE_KEY = "RSAHaoFangKey1";        /**      * RSA最大加密明文大小     */    private static final int MAX_ENCRYPT_BLOCK = 117;        /**      * RSA最大解密密文大小     */    private static final int MAX_DECRYPT_BLOCK = 128;    /**      * 生成密钥对(公钥和私钥)     * @return     * @throws Exception     */    public static Map<String, Object> genKeyPair() throws Exception {        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);        keyPairGen.initialize(1024);        KeyPair keyPair = keyPairGen.generateKeyPair();        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();        Map<String, Object> keyMap = new HashMap<String, Object>(2);        keyMap.put(PUBLIC_KEY, publicKey);        keyMap.put(PRIVATE_KEY, privateKey);        return keyMap;    }        /**      * 用私钥对信息生成数字签名     * @param data 已加密数据     * @param privateKey 私钥(BASE64编码)     * @return     * @throws Exception     */    public static String sign(byte[] data, String privateKey) throws Exception {        byte[] keyBytes = RsaBase64Utils.decode(privateKey);        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);        PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);        signature.initSign(privateK);        signature.update(data);        return RsaBase64Utils.encode(signature.sign());    }    /**      * 校验数字签名     * @param data 已加密数据     * @param publicKey 公钥(BASE64编码)     * @param sign 数字签名      * @return     * @throws Exception     *      */    public static boolean verify(byte[] data, String publicKey, String sign)            throws Exception {        byte[] keyBytes = RsaBase64Utils.decode(publicKey);        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);        PublicKey publicK = keyFactory.generatePublic(keySpec);        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);        signature.initVerify(publicK);        signature.update(data);        return signature.verify(RsaBase64Utils.decode(sign));    }    /**      * 私钥解密      * @param encryptedData 已加密数据     * @param privateKey 私钥(BASE64编码)     * @return     * @throws Exception     */    public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey)            throws Exception {        byte[] keyBytes = RsaBase64Utils.decode(privateKey);        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);        Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");//keyFactory.getAlgorithm()        cipher.init(Cipher.DECRYPT_MODE, privateK);        int inputLen = encryptedData.length;        ByteArrayOutputStream out = new ByteArrayOutputStream();        int offSet = 0;        byte[] cache;        int i = 0;        // 对数据分段解密        while (inputLen - offSet > 0) {            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {                cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);            } else {                cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);            }            out.write(cache, 0, cache.length);            i++;            offSet = i * MAX_DECRYPT_BLOCK;        }        byte[] decryptedData = out.toByteArray();        out.close();        return decryptedData;    }    /**      * 公钥解密     * @param encryptedData 已加密数据     * @param publicKey 公钥(BASE64编码)     * @return     * @throws Exception     */    public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey)            throws Exception {        byte[] keyBytes = RsaBase64Utils.decode(publicKey);        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);        Key publicK = keyFactory.generatePublic(x509KeySpec);        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");        cipher.init(Cipher.DECRYPT_MODE, publicK);        int inputLen = encryptedData.length;        ByteArrayOutputStream out = new ByteArrayOutputStream();        int offSet = 0;        byte[] cache;        int i = 0;        // 对数据分段解密        while (inputLen - offSet > 0) {            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {                cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);            } else {                cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);            }            out.write(cache, 0, cache.length);            i++;            offSet = i * MAX_DECRYPT_BLOCK;        }        byte[] decryptedData = out.toByteArray();        out.close();        return decryptedData;    }    /**      * 公钥加密     * @param data 源数据     * @param publicKey 公钥(BASE64编码)     * @return     * @throws Exception     */    public static byte[] encryptByPublicKey(String source, String publicKey)throws Exception {        byte[] keyBytes = RsaBase64Utils.decode(publicKey);        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);        Key publicK = keyFactory.generatePublic(x509KeySpec);        // 对数据加密        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());        cipher.init(Cipher.ENCRYPT_MODE, publicK);        byte[] data = source.getBytes();        int inputLen = data.length;        ByteArrayOutputStream out = new ByteArrayOutputStream();        int offSet = 0;        byte[] cache;        int i = 0;        // 对数据分段加密        while (inputLen - offSet > 0) {            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {                cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);            } else {                cache = cipher.doFinal(data, offSet, inputLen - offSet);            }            out.write(cache, 0, cache.length);            i++;            offSet = i * MAX_ENCRYPT_BLOCK;        }        byte[] encryptedData = out.toByteArray();        out.close();        return encryptedData;    }    /**      * 私钥加密     * @param data 源数据     * @param privateKey 私钥(BASE64编码)     * @return     * @throws Exception     */    public static byte[] encryptByPrivateKey(byte[] data, String privateKey)            throws Exception {        byte[] keyBytes = RsaBase64Utils.decode(privateKey);        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);        Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());        cipher.init(Cipher.ENCRYPT_MODE, privateK);        int inputLen = data.length;        ByteArrayOutputStream out = new ByteArrayOutputStream();        int offSet = 0;        byte[] cache;        int i = 0;        // 对数据分段加密        while (inputLen - offSet > 0) {            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {                cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);            } else {                cache = cipher.doFinal(data, offSet, inputLen - offSet);            }            out.write(cache, 0, cache.length);            i++;            offSet = i * MAX_ENCRYPT_BLOCK;        }        byte[] encryptedData = out.toByteArray();        out.close();        return encryptedData;    }    /**      * 获取私钥     * @param keyMap 密钥对     * @return     * @throws Exception     */    public static String getPrivateKey(Map<String, Object> keyMap)            throws Exception {        Key key = (Key) keyMap.get(PRIVATE_KEY);        return RsaBase64Utils.encode(key.getEncoded());    }    /**      * 获取公钥     * @param keyMap 密钥对     * @return     * @throws Exception     */    public static String getPublicKey(Map<String, Object> keyMap)            throws Exception {        Key key = (Key) keyMap.get(PUBLIC_KEY);        return RsaBase64Utils.encode(key.getEncoded());    }}

package com.pingan.haofang.connector.common.secretutil;import java.util.Map;public class RSATester {    static String publicKey;    static String privateKey;    static {        try {            Map<String, Object> keyMap = RSAUtils.genKeyPair();            publicKey = RSAUtils.getPublicKey(keyMap);            privateKey = RSAUtils.getPrivateKey(keyMap);            System.err.println("公钥: \n\r" + publicKey);            System.err.println("私钥: \n\r" + privateKey);        } catch (Exception e) {            e.printStackTrace();        }    }        public static void main(String[] args) throws Exception {        test();        ///testSign();    }    static void test() throws Exception {        System.err.println("公钥加密——私钥解密");        String source = "23452345sr这是一行没有任何意义的文字,你看完了等于没看,不是吗fgsdfgaet WEDasDsdgaaw?";        System.out.println("\r加密前文字:\r\n" + source);        byte[] encodedData = RSAUtils.encryptByPublicKey(source, publicKey);        System.out.println("加密后文字:\r\n" + new String(encodedData));        byte[] decodedData = RSAUtils.decryptByPrivateKey(encodedData, privateKey);        String target = new String(decodedData);        System.out.println("解密后文字: \r\n" + target);    }/*    static void testSign() throws Exception {        System.err.println("私钥加密——公钥解密");        String source = "这是一行测试RSA数字签名的无意义文字";        System.out.println("原文字:\r\n" + source);        byte[] data = source.getBytes();        byte[] encodedData = RSAUtils.encryptByPrivateKey(data, privateKey);        System.out.println("加密后:\r\n" + new String(encodedData));        byte[] decodedData = RSAUtils.decryptByPublicKey(encodedData, publicKey);        String target = new String(decodedData);        System.out.println("解密后: \r\n" + target);        System.err.println("私钥签名——公钥验证签名");        String sign = RSAUtils.sign(encodedData, privateKey);        System.err.println("签名:\r" + sign);        boolean status = RSAUtils.verify(encodedData, publicKey, sign);        System.err.println("验证结果:\r" + status);    }*/}

package com.pingan.haofang.connector.common.secretutil;  import java.io.ByteArrayInputStream;  import java.io.ByteArrayOutputStream;  import java.io.File;  import java.io.FileInputStream;  import java.io.FileOutputStream;  import java.io.InputStream;  import java.io.OutputStream;  import com.pingan.haofang.connector.common.creditutils.Base64PYZX;  /** * @Title: BASE64编码解码工具包  * @Description: 依赖javabase64-1.3.1.jar * @Team: 新金融业务研发团队 * @Author wangcs * @Date 2017年05月27日 * @Version V1.0 */public class RsaBase64Utils {        /**     * 文件读取缓冲区大小      */      private final int CACHE_SIZE = 1024;              /**     * BASE64字符串解码为二进制数据       * @param base64      * @return      * @throws Exception      */      public static byte[] decode(String base64) throws Exception {          return new Base64PYZX().decode(base64);      }            /**     * 二进制数据编码为BASE64字符串       * @param bytes      * @return      * @throws Exception      */      public static String encode(byte[] bytes) throws Exception {          return new String(new Base64PYZX().encode(bytes));      }            /**      * 将文件编码为BASE64字符串      * 大文件慎用,可能会导致内存溢出      * @param filePath 文件绝对路径      * @return      * @throws Exception      */      public String encodeFile(String filePath) throws Exception {          byte[] bytes = fileToByte(filePath);          return encode(bytes);      }            /**      * BASE64字符串转回文件      * @param filePath 文件绝对路径      * @param base64 编码字符串      * @throws Exception      */      public void decodeToFile(String filePath, String base64) throws Exception {          byte[] bytes = decode(base64);          byteArrayToFile(bytes, filePath);      }            /**      * 文件转换为二进制数组       * @param filePath 文件路径      * @return      * @throws Exception      */      public byte[] fileToByte(String filePath) throws Exception {          byte[] data = new byte[0];          File file = new File(filePath);          if (file.exists()) {              FileInputStream in = new FileInputStream(file);              ByteArrayOutputStream out = new ByteArrayOutputStream(2048);              byte[] cache = new byte[CACHE_SIZE];              int nRead = 0;              while ((nRead = in.read(cache)) != -1) {                  out.write(cache, 0, nRead);                  out.flush();              }              out.close();              in.close();              data = out.toByteArray();           }          return data;      }            /**       * 二进制数据写文件       * @param bytes 二进制数据      * @param filePath 文件生成目录      */      public void byteArrayToFile(byte[] bytes, String filePath) throws Exception {          InputStream in = new ByteArrayInputStream(bytes);             File destFile = new File(filePath);          if (!destFile.getParentFile().exists()) {              destFile.getParentFile().mkdirs();          }          destFile.createNewFile();          OutputStream out = new FileOutputStream(destFile);          byte[] cache = new byte[CACHE_SIZE];          int nRead = 0;          while ((nRead = in.read(cache)) != -1) {                 out.write(cache, 0, nRead);              out.flush();          }          out.close();          in.close();      }              }  

package com.pingan.haofang.connector.common.creditutils;/** * <p>Title: 深圳市个人信用征信系统</p> * <p>Description: Base64编码,提供二进制流与字符串之间的转换</p> * <p>Copyright: Copyright (c) 2005 Sino-Hawk Credit Rating Corpration. All rights reserved.</p> * @version 2.0 */public class Base64PYZX{/** * how we separate lines, e.g. \n, \r\n, \r etc. */private String lineSeparator = System.getProperty("line.separator");/** * max chars per line, excluding lineSeparator.  A multiple of 4. */private int lineLength = 72;/* constructor */public Base64PYZX (){}/** * Encode an arbitrary array of bytes as Base64 printable ASCII. * It will be broken into lines of 72 chars each.  The last line is not * terminated with a line separator. * The output will always have an even multiple of data characters, * exclusive of \n.  It is padded out with =. */public String encode (byte[] b){// Each group or partial group of 3 bytes becomes four chars// covered quotientint outputLength = ((b.length + 2) / 3) * 4;// account for trailing newlines, on all but the very last lineif (lineLength != 0){int lines = (outputLength + lineLength - 1) / lineLength - 1;if (lines > 0){outputLength += lines * lineSeparator.length();}}// must be local for recursion to work.StringBuffer sb = new StringBuffer(outputLength);// must be local for recursion to work.int linePos = 0;// first deal with even multiples of 3 bytes.int len = (b.length / 3) * 3;int leftover = b.length - len;for (int i = 0;i < len;i += 3){// Start a new line if next 4 chars won't fit on the current line// We can't encapsulete the following code since the variable need to// be local to this incarnation of encode.linePos += 4;if (linePos > lineLength){if (lineLength != 0){sb.append(lineSeparator);}linePos = 4;}// get next three bytes in unsigned form lined up,// in big-endian orderint combined = b[i + 0] & 0xff;combined <<= 8;combined |= b[i + 1] & 0xff;combined <<= 8;combined |= b[i + 2] & 0xff;// break those 24 bits into a 4 groups of 6 bits,// working LSB to MSB.int c3 = combined & 0x3f;combined >>>= 6;int c2 = combined & 0x3f;combined >>>= 6;int c1 = combined & 0x3f;combined >>>= 6;int c0 = combined & 0x3f;// Translate into the equivalent alpha character// emitting them in big-endian order.sb.append(valueToChar[c0]);sb.append(valueToChar[c1]);sb.append(valueToChar[c2]);sb.append(valueToChar[c3]);}// deal with leftover bytesswitch (leftover){case 0:default:// nothing to dobreak;case 1:// One leftover byte generates xx==// Start a new line if next 4 chars won't fit on the current linelinePos += 4;if (linePos > lineLength){if (lineLength != 0){sb.append(lineSeparator);}linePos = 4;}// Handle this recursively with a faked complete triple.// Throw away last two chars and replace with ==sb.append(encode(new byte[]{b[len],0,0}).substring(0,2));sb.append("==");break;case 2:// Two leftover bytes generates xxx=// Start a new line if next 4 chars won't fit on the current linelinePos += 4;if (linePos > lineLength){if (lineLength != 0){sb.append(lineSeparator);}linePos = 4;}// Handle this recursively with a faked complete triple.// Throw away last char and replace with =sb.append(encode(new byte[]{b[len],b[len + 1],0}).substring(0,3));sb.append("=");break;} // end switch;if (outputLength != sb.length()){System.out.println("oops: minor program flaw: output length mis-estimated");System.out.println("estimate:" + outputLength);System.out.println("actual:" + sb.length());}return sb.toString();} // end encode/** * decode a well-formed complete Base64 string back into an array of bytes. * It must have an even multiple of 4 data characters (not counting \n), * padded out with = as needed. */public byte[] decode (String s){// estimate worst case size of output array, no embedded newlines.byte[] b = new byte[(s.length() / 4) * 3];// tracks where we are in a cycle of 4 input chars.int cycle = 0;// where we combine 4 groups of 6 bits and take apart as 3 groups of 8.int combined = 0;// how many bytes we have prepared.int j = 0;// will be an even multiple of 4 chars, plus some embedded \nint len = s.length();int dummies = 0;for (int i = 0;i < len;i++){int c = s.charAt(i);int value = (c <= 255) ? charToValue[c] : IGNORE;// there are two magic values PAD (=) and IGNORE.switch (value){case IGNORE:// e.g. \n, just ignore it.break;case PAD:value = 0;dummies++;// fallthroughdefault:/* regular value character */switch (cycle){case 0:combined = value;cycle = 1;break;case 1:combined <<= 6;combined |= value;cycle = 2;break;case 2:combined <<= 6;combined |= value;cycle = 3;break;case 3:combined <<= 6;combined |= value;// we have just completed a cycle of 4 chars.// the four 6-bit values are in combined in big-endian order// peel them off 8 bits at a time working lsb to msb// to get our original 3 8-bit bytes backb[j + 2] = (byte)combined;combined >>>= 8;b[j + 1] = (byte)combined;combined >>>= 8;b[j] = (byte)combined;j += 3;cycle = 0;break;}break;}} // end forif (cycle != 0){throw new ArrayIndexOutOfBoundsException("Input to decode not an even multiple of 4 characters; pad with =.");}j -= dummies;if (b.length != j){byte[] b2 = new byte[j];System.arraycopy(b,0,b2,0,j);b = b2;}return b;} // end decode/** * determines how long the lines are that are generated by encode. * Ignored by decode. * @param length 0 means no newlines inserted. Must be a multiple of 4. */public void setLineLength (int length){this.lineLength = (length / 4) * 4;}/** * How lines are separated. * Ignored by decode. * @param lineSeparator may be "" but not null. * Usually contains only a combination of chars \n and \r. * Could be any chars not in set A-Z a-z 0-9 + /. */public void setLineSeparator (String lineSeparator){this.lineSeparator = lineSeparator;}/** * letter of the alphabet used to encode binary values 0..63 */static final char[] valueToChar = new char[64];/** * binary value encoded by a given letter of the alphabet 0..63 */static final int[] charToValue = new int[256];/** * Marker value for chars we just ignore, e.g. \n \r high ascii */static final int IGNORE = -1;/** * Marker for = trailing pad */static final int PAD = -2;static/* initialise valueToChar and charToValue tables */{// build translate valueToChar table only once.// 0..25 -> 'A'..'Z'for (int i = 0;i <= 25;i++){valueToChar[i] = (char)('A' + i);// 26..51 -> 'a'..'z'}for (int i = 0;i <= 25;i++){valueToChar[i + 26] = (char)('a' + i);// 52..61 -> '0'..'9'}for (int i = 0;i <= 9;i++){valueToChar[i + 52] = (char)('0' + i);}valueToChar[62] = '+';valueToChar[63] = '/';// build translate charToValue table only once.for (int i = 0;i < 256;i++){charToValue[i] = IGNORE; // default is to ignore}for (int i = 0;i < 64;i++){charToValue[valueToChar[i]] = i;}charToValue['='] = PAD;}/** * used to disable test driver */private static final boolean debug = false;/** * debug display array */public static void show (byte[] b){for (int i = 0;i < b.length;i++){System.out.print(Integer.toHexString(b[i] & 0xff) + " ");}System.out.println();}/** * debug display array */public static void display (byte[] b){for (int i = 0;i < b.length;i++){System.out.print((char)b[i]);}System.out.println();}/** * test driver */public static void main (String[] args){if (debug){byte[] a = {(byte)0xfc,(byte)0x0f,(byte)0xc0};byte[] b = {(byte)0x03,(byte)0xf0,(byte)0x3f};byte[] c = {(byte)0x00,(byte)0x00,(byte)0x00};byte[] d = {(byte)0xff,(byte)0xff,(byte)0xff};byte[] e = {(byte)0xfc,(byte)0x0f,(byte)0xc0,(byte)1};byte[] f = {(byte)0xfc,(byte)0x0f,(byte)0xc0,(byte)1,(byte)2};byte[] g = {(byte)0xfc,(byte)0x0f,(byte)0xc0,(byte)1,(byte)2,(byte)3};byte[] h = "AAAAAAAAAAB".getBytes();show(a);show(b);show(c);show(d);show(e);show(f);show(g);show(h);Base64PYZX b64 = new Base64PYZX();show(b64.decode(b64.encode(a)));show(b64.decode(b64.encode(b)));show(b64.decode(b64.encode(c)));show(b64.decode(b64.encode(d)));show(b64.decode(b64.encode(e)));show(b64.decode(b64.encode(f)));show(b64.decode(b64.encode(g)));show(b64.decode(b64.encode(h)));b64.setLineLength(8);show((b64.encode(h)).getBytes());}} // end main} // end Base64

原创粉丝点击