依舊是練習的產物,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; } }