Java非對稱加密RSA工具類v1.1

依舊是練習的產物,java的加密算法有不少,惋惜用起來很痛苦(我的感覺),有時間的話打算作個簡化過程的全部加密算法工具類,以前已經寫過一個包含MD五、SHA一、DES、AES、異或的簡單工具類

這裏簡單講一下RSA:

咱們平時所知道的密碼什麼的都基本是一個,DES、AES的加密解密也都是用同一個密碼,可是RSA就不同了,RSA有2個密碼:公鑰、私鑰

爲何要用2個密碼?要怎麼用?
用2個密碼天然是爲了數據的安全,防止丟失數據後被人惡意破解。
至於怎麼用,其實就是用公鑰加密後只能用私鑰解密,私鑰加密後只能用公鑰解密

就以支付寶的集成爲例,你得在本地生成公鑰跟私鑰,而後上傳給支付寶,以後傳輸數據的時候就是用這對密碼來加解密的。(固然,加解密的步驟支付寶已經幫你作了,你是不用去寫RSA的代碼的)

題外話:其實我一直以爲支付寶這個生成公鑰私鑰能夠在支付寶平臺作的,每次都要我在本地生成,而後還要去傳給支付寶平臺,真的有一點點、一點點的煩。。。

---
v1.1 加入分段處理java

 

package com.lwx.encrypt;
 
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
 
import javax.crypto.Cipher;
 
public class RSA {
 
    public static void main(String ...args){
        RSA rsa = RSA.create();
        String pubKey = rsa.getPublicKey();
        String priKey = rsa.getPrivateKey();
        //原文
        StringBuffer res = new StringBuffer();
        for (int i = 0; i < 40; i++) {
            res.append("測試");
        }
        System.out.println("原文對比:"+res.toString());
        System.out.println("------------");
        String enStr = rsa.encodeByPublicKey(res.toString(), pubKey);
        String deStr = rsa.decodeByPrivateKey(enStr, priKey);
        System.out.println("公鑰加密:"+enStr);
        System.out.println("私鑰解密:"+deStr);
        System.out.println("------------");
        enStr = rsa.encodeByPrivateKey(res.toString(), priKey);
        deStr = rsa.decodeByPublicKey(enStr, pubKey);
        System.out.println("私鑰加密:"+enStr);
        System.out.println("公鑰解密:"+deStr);
    }
 
    public static final String KEY_ALGORITHM = "RSA";
    public static final String split = " ";//分隔符
    public static final int max = 117;//加密分段長度//不可超過117
 
    private static RSA me;
    private RSA(){}//單例
    public static RSA create(){
        if (me==null) {
            me = new RSA();
        }
        //生成公鑰、私鑰
        try {
            KeyPairGenerator kpg = KeyPairGenerator.getInstance(KEY_ALGORITHM);
            kpg.initialize(1024);
            KeyPair kp = kpg.generateKeyPair();
            me.publicKey = (RSAPublicKey) kp.getPublic();
            me.privateKey = (RSAPrivateCrtKey) kp.getPrivate();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return me;
    }
 
    private RSAPublicKey publicKey;
    private RSAPrivateCrtKey privateKey;
 
    /**獲取公鑰*/
    public String getPublicKey(){
        return parseByte2HexStr(publicKey.getEncoded());
    }
 
    /**獲取私鑰*/
    public String getPrivateKey(){
        return parseByte2HexStr(privateKey.getEncoded());
    }
 
    /**加密-公鑰*/
    public String encodeByPublicKey(String res,String key){
        byte[] resBytes = res.getBytes();
        byte[] keyBytes = parseHexStr2Byte(key);//先把公鑰轉爲2進制
        StringBuffer result = new StringBuffer();//結果
        //若是超過了100個字節就分段
        if (keyBytes.length<=max) {//不超過直接返回便可
            return encodePub(resBytes, keyBytes);
        }else {
            int size = resBytes.length/max + (resBytes.length%max>0?1:0);
            for (int i = 0; i < size; i++) {
                int len = i==size-1?resBytes.length%max:max;
                byte[] bs = new byte[len];//臨時數組
                System.arraycopy(resBytes, i*max, bs, 0, len);
                result.append(encodePub(bs, keyBytes));
                if(i!=size-1)result.append(split);
            }
            return result.toString();
        }
    }
    /**加密-私鑰*/
    public String encodeByPrivateKey(String res,String key){
        byte[] resBytes = res.getBytes();
        byte[] keyBytes = parseHexStr2Byte(key);
        StringBuffer result = new StringBuffer();
        //若是超過了100個字節就分段
        if (keyBytes.length<=max) {//不超過直接返回便可
            return encodePri(resBytes, keyBytes);
        }else {
            int size = resBytes.length/max + (resBytes.length%max>0?1:0);
            for (int i = 0; i < size; i++) {
                int len = i==size-1?resBytes.length%max:max;
                byte[] bs = new byte[len];//臨時數組
                System.arraycopy(resBytes, i*max, bs, 0, len);
                result.append(encodePri(bs, keyBytes));
                if(i!=size-1)result.append(split);
            }
            return result.toString();
        }
    }
    /**解密-公鑰*/
    public String decodeByPublicKey(String res,String key){
        byte[] keyBytes = parseHexStr2Byte(key);
        //先分段
        String[] rs = res.split("\\"+split);
        //分段解密
        if(rs!=null){
            int len = 0;
            //組合byte[]
            byte[] result = new byte[rs.length*max];
            for (int i = 0; i < rs.length; i++) {
                byte[] bs = decodePub(parseHexStr2Byte(rs[i]), keyBytes);
                System.arraycopy(bs, 0, result, i*max, bs.length);
                len+=bs.length;
            }
            byte[] newResult = new byte[len];
            System.arraycopy(result, 0, newResult, 0, len);
            //還原字符串
            return new String(newResult);
        }
        return null;
    }
    /**解密-私鑰*/
    public String decodeByPrivateKey(String res,String key){
        byte[] keyBytes = parseHexStr2Byte(key);
        //先分段
        String[] rs = res.split("\\"+split);
        //分段解密
        if(rs!=null){
            int len = 0;
            //組合byte[]
            byte[] result = new byte[rs.length*max];
            for (int i = 0; i < rs.length; i++) {
                byte[] bs = decodePri(parseHexStr2Byte(rs[i]), keyBytes);
                System.arraycopy(bs, 0, result, i*max, bs.length);
                len+=bs.length;
            }
            byte[] newResult = new byte[len];
            System.arraycopy(result, 0, newResult, 0, len);
            //還原字符串
            return new String(newResult);
        }
        return null;
    }
 
    /**將二進制轉換成16進制 */
    public static String parseByte2HexStr(byte buf[]) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
            String hex = Integer.toHexString(buf[i] & 0xFF);  
            if (hex.length() == 1) {
                hex = '0' + hex;  
            }
            sb.append(hex.toUpperCase());  
        }
        return sb.toString();  
    }
    /**將16進制轉換爲二進制*/
    public static byte[] parseHexStr2Byte(String hexStr) {
        if (hexStr.length() < 1)
            return null;
        byte[] result = new byte[hexStr.length()/2];
        for (int i = 0;i< hexStr.length()/2; i++) {
            int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);  
            int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);  
            result[i] = (byte) (high * 16 + low);  
        }
        return result;  
    }
 
    /**加密-公鑰-無分段*/
    private String encodePub(byte[] res,byte[] keyBytes){
        X509EncodedKeySpec x5 = new X509EncodedKeySpec(keyBytes);//用2進制的公鑰生成x509
        try {
            KeyFactory kf = KeyFactory.getInstance(KEY_ALGORITHM);
            Key pubKey = kf.generatePublic(x5);//用KeyFactory把x509生成公鑰pubKey
            Cipher cp = Cipher.getInstance(kf.getAlgorithm());//生成相應的Cipher
            cp.init(Cipher.ENCRYPT_MODE, pubKey);//給cipher初始化爲加密模式,以及傳入公鑰pubKey
            return parseByte2HexStr(cp.doFinal(res));//以16進制的字符串返回
        } catch (Exception e) {
            System.out.println("公鑰加密失敗");
            e.printStackTrace();
        }
        return null;
    }
    /**加密-私鑰-無分段*/
    private String encodePri(byte[] res,byte[] keyBytes){
        PKCS8EncodedKeySpec pk8 = new PKCS8EncodedKeySpec(keyBytes);
        try {
            KeyFactory kf = KeyFactory.getInstance(KEY_ALGORITHM);
            Key priKey = kf.generatePrivate(pk8);
            Cipher cp = Cipher.getInstance(kf.getAlgorithm());
            cp.init(Cipher.ENCRYPT_MODE, priKey);
            return parseByte2HexStr(cp.doFinal(res));
        } catch (Exception e) {
            System.out.println("私鑰加密失敗");
            e.printStackTrace();
        }
        return null;
    }
    /**解密-公鑰-無分段*/
    private byte[] decodePub(byte[] res,byte[] keyBytes){
        X509EncodedKeySpec x5 = new X509EncodedKeySpec(keyBytes);
        try {
            KeyFactory kf = KeyFactory.getInstance(KEY_ALGORITHM);
            Key pubKey = kf.generatePublic(x5);
            Cipher cp = Cipher.getInstance(kf.getAlgorithm());
            cp.init(Cipher.DECRYPT_MODE, pubKey);
            return cp.doFinal(res);
        } catch (Exception e) {
            System.out.println("公鑰解密失敗");
            e.printStackTrace();
        }
        return null;
    }
    /**解密-私鑰-無分段*/
    private byte[] decodePri(byte[] res,byte[] keyBytes){
        PKCS8EncodedKeySpec pk8 = new PKCS8EncodedKeySpec(keyBytes);
        try {
            KeyFactory kf = KeyFactory.getInstance(KEY_ALGORITHM);
            Key priKey = kf.generatePrivate(pk8);
            Cipher cp = Cipher.getInstance(kf.getAlgorithm());
            cp.init(Cipher.DECRYPT_MODE, priKey);
            return cp.doFinal(res);
        } catch (Exception e) {
            System.out.println("私鑰解密失敗");
            e.printStackTrace();
        }
        return null;
    }
 
}
相關文章
相關標籤/搜索