由于項目中要傳輸和保存敏感數(shù)據(jù),,于是寫了一個RSA進行加密解密的工具類.大家如有需要,可以參考下. 加密和解密的代碼如下: public class RSAEncrypt { /** * 字節(jié)數(shù)據(jù)轉(zhuǎn)字符串專用集合 */ private static final char[] HEX_CHAR = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; /** * 隨機生成密鑰對 */ public static void genKeyPair(String filePath) { // KeyPairGenerator類用于生成公鑰和私鑰對,,基于RSA算法生成對象 KeyPairGenerator keyPairGen = null; try { keyPairGen = KeyPairGenerator.getInstance('RSA'); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 初始化密鑰對生成器,,密鑰大小為96-1024位 keyPairGen.initialize(1024,new SecureRandom()); // 生成一個密鑰對,,保存在keyPair中 KeyPair keyPair = keyPairGen.generateKeyPair(); // 得到私鑰 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到公鑰 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); try { // 得到公鑰字符串 String publicKeyString = Base64.encode(publicKey.getEncoded()); // 得到私鑰字符串 String privateKeyString = Base64.encode(privateKey.getEncoded()); // 將密鑰對寫入到文件 FileWriter pubfw = new FileWriter(filePath + '/publicKey.keystore'); FileWriter prifw = new FileWriter(filePath + '/privateKey.keystore'); BufferedWriter pubbw = new BufferedWriter(pubfw); BufferedWriter pribw = new BufferedWriter(prifw); pubbw.write(publicKeyString); pribw.write(privateKeyString); pubbw.flush(); pubbw.close(); pubfw.close(); pribw.flush(); pribw.close(); prifw.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 從文件中輸入流中加載公鑰 * * @param in * 公鑰輸入流 * @throws Exception * 加載公鑰時產(chǎn)生的異常 */ public static String loadPublicKeyByFile(String path) throws Exception { try { BufferedReader br = new BufferedReader(new FileReader(path + '/publicKey.keystore')); String readLine = null; StringBuilder sb = new StringBuilder(); while ((readLine = br.readLine()) != null) { sb.append(readLine); } br.close(); return sb.toString(); } catch (IOException e) { throw new Exception('公鑰數(shù)據(jù)流讀取錯誤'); } catch (NullPointerException e) { throw new Exception('公鑰輸入流為空'); } } /** * 從字符串中加載公鑰 * * @param publicKeyStr * 公鑰數(shù)據(jù)字符串 * @throws Exception * 加載公鑰時產(chǎn)生的異常 */ public static RSAPublicKey loadPublicKeyByStr(String publicKeyStr) throws Exception { try { byte[] buffer = Base64.decode(publicKeyStr); KeyFactory keyFactory = KeyFactory.getInstance('RSA'); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer); return (RSAPublicKey) keyFactory.generatePublic(keySpec); } catch (NoSuchAlgorithmException e) { throw new Exception('無此算法'); } catch (InvalidKeySpecException e) { throw new Exception('公鑰非法'); } catch (NullPointerException e) { throw new Exception('公鑰數(shù)據(jù)為空'); } } /** * 從文件中加載私鑰 * * @param keyFileName * 私鑰文件名 * @return 是否成功 * @throws Exception */ public static String loadPrivateKeyByFile(String path) throws Exception { try { BufferedReader br = new BufferedReader(new FileReader(path + '/privateKey.keystore')); String readLine = null; StringBuilder sb = new StringBuilder(); while ((readLine = br.readLine()) != null) { sb.append(readLine); } br.close(); return sb.toString(); } catch (IOException e) { throw new Exception('私鑰數(shù)據(jù)讀取錯誤'); } catch (NullPointerException e) { throw new Exception('私鑰輸入流為空'); } } public static RSAPrivateKey loadPrivateKeyByStr(String privateKeyStr) throws Exception { try { byte[] buffer = Base64.decode(privateKeyStr); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer); KeyFactory keyFactory = KeyFactory.getInstance('RSA'); return (RSAPrivateKey) keyFactory.generatePrivate(keySpec); } catch (NoSuchAlgorithmException e) { throw new Exception('無此算法'); } catch (InvalidKeySpecException e) { throw new Exception('私鑰非法'); } catch (NullPointerException e) { throw new Exception('私鑰數(shù)據(jù)為空'); } } /** * 公鑰加密過程 * * @param publicKey * 公鑰 * @param plainTextData * 明文數(shù)據(jù) * @return * @throws Exception * 加密過程中的異常信息 */ public static byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData) throws Exception { if (publicKey == null) { throw new Exception('加密公鑰為空, 請設(shè)置'); } Cipher cipher = null; try { // 使用默認RSA cipher = Cipher.getInstance('RSA'); // cipher= Cipher.getInstance('RSA', new BouncyCastleProvider()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] output = cipher.doFinal(plainTextData); return output; } catch (NoSuchAlgorithmException e) { throw new Exception('無此加密算法'); } catch (NoSuchPaddingException e) { e.printStackTrace(); return null; } catch (InvalidKeyException e) { throw new Exception('加密公鑰非法,請檢查'); } catch (IllegalBlockSizeException e) { throw new Exception('明文長度非法'); } catch (BadPaddingException e) { throw new Exception('明文數(shù)據(jù)已損壞'); } } /** * 私鑰加密過程 * * @param privateKey * 私鑰 * @param plainTextData * 明文數(shù)據(jù) * @return * @throws Exception * 加密過程中的異常信息 */ public static byte[] encrypt(RSAPrivateKey privateKey, byte[] plainTextData) throws Exception { if (privateKey == null) { throw new Exception('加密私鑰為空, 請設(shè)置'); } Cipher cipher = null; try { // 使用默認RSA cipher = Cipher.getInstance('RSA'); cipher.init(Cipher.ENCRYPT_MODE, privateKey); byte[] output = cipher.doFinal(plainTextData); return output; } catch (NoSuchAlgorithmException e) { throw new Exception('無此加密算法'); } catch (NoSuchPaddingException e) { e.printStackTrace(); return null; } catch (InvalidKeyException e) { throw new Exception('加密私鑰非法,請檢查'); } catch (IllegalBlockSizeException e) { throw new Exception('明文長度非法'); } catch (BadPaddingException e) { throw new Exception('明文數(shù)據(jù)已損壞'); } } /** * 私鑰解密過程 * * @param privateKey * 私鑰 * @param cipherData * 密文數(shù)據(jù) * @return 明文 * @throws Exception * 解密過程中的異常信息 */ public static byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData) throws Exception { if (privateKey == null) { throw new Exception('解密私鑰為空, 請設(shè)置'); } Cipher cipher = null; try { // 使用默認RSA cipher = Cipher.getInstance('RSA'); // cipher= Cipher.getInstance('RSA', new BouncyCastleProvider()); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] output = cipher.doFinal(cipherData); return output; } catch (NoSuchAlgorithmException e) { throw new Exception('無此解密算法'); } catch (NoSuchPaddingException e) { e.printStackTrace(); return null; } catch (InvalidKeyException e) { throw new Exception('解密私鑰非法,請檢查'); } catch (IllegalBlockSizeException e) { throw new Exception('密文長度非法'); } catch (BadPaddingException e) { throw new Exception('密文數(shù)據(jù)已損壞'); } } /** * 公鑰解密過程 * * @param publicKey * 公鑰 * @param cipherData * 密文數(shù)據(jù) * @return 明文 * @throws Exception * 解密過程中的異常信息 */ public static byte[] decrypt(RSAPublicKey publicKey, byte[] cipherData) throws Exception { if (publicKey == null) { throw new Exception('解密公鑰為空, 請設(shè)置'); } Cipher cipher = null; try { // 使用默認RSA cipher = Cipher.getInstance('RSA'); // cipher= Cipher.getInstance('RSA', new BouncyCastleProvider()); cipher.init(Cipher.DECRYPT_MODE, publicKey); byte[] output = cipher.doFinal(cipherData); return output; } catch (NoSuchAlgorithmException e) { throw new Exception('無此解密算法'); } catch (NoSuchPaddingException e) { e.printStackTrace(); return null; } catch (InvalidKeyException e) { throw new Exception('解密公鑰非法,請檢查'); } catch (IllegalBlockSizeException e) { throw new Exception('密文長度非法'); } catch (BadPaddingException e) { throw new Exception('密文數(shù)據(jù)已損壞'); } } /** * 字節(jié)數(shù)據(jù)轉(zhuǎn)十六進制字符串 * * @param data * 輸入數(shù)據(jù) * @return 十六進制內(nèi)容 */ public static String byteArrayToString(byte[] data) { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < data.length; i++) { // 取出字節(jié)的高四位 作為索引得到相應(yīng)的十六進制標(biāo)識符 注意無符號右移 stringBuilder.append(HEX_CHAR[(data[i] & 0xf0) >>> 4]); // 取出字節(jié)的低四位 作為索引得到相應(yīng)的十六進制標(biāo)識符 stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]); if (i < data.length - 1) { stringBuilder.append(' '); } } return stringBuilder.toString(); } } 簽名及校驗的代碼如下: public class RSASignature{ /** * 簽名算法 */ public static final String SIGN_ALGORITHMS = 'SHA1WithRSA'; /** * RSA簽名 * @param content 待簽名數(shù)據(jù) * @param privateKey 商戶私鑰 * @param encode 字符集編碼 * @return 簽名值 */ public static String sign(String content, String privateKey, String encode) { try { PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec( Base64.decode(privateKey) ); KeyFactory keyf = KeyFactory.getInstance('RSA'); PrivateKey priKey = keyf.generatePrivate(priPKCS8); java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS); signature.initSign(priKey); signature.update( content.getBytes(encode)); byte[] signed = signature.sign(); return Base64.encode(signed); } catch (Exception e) { e.printStackTrace(); } return null; } public static String sign(String content, String privateKey) { try { PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec( Base64.decode(privateKey) ); KeyFactory keyf = KeyFactory.getInstance('RSA'); PrivateKey priKey = keyf.generatePrivate(priPKCS8); java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS); signature.initSign(priKey); signature.update( content.getBytes()); byte[] signed = signature.sign(); return Base64.encode(signed); } catch (Exception e) { e.printStackTrace(); } return null; } /** * RSA驗簽名檢查 * @param content 待簽名數(shù)據(jù) * @param sign 簽名值 * @param publicKey 分配給開發(fā)商公鑰 * @param encode 字符集編碼 * @return 布爾值 */ public static boolean doCheck(String content, String sign, String publicKey,String encode) { try { KeyFactory keyFactory = KeyFactory.getInstance('RSA'); byte[] encodedKey = Base64.decode(publicKey); PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey)); java.security.Signature signature = java.security.Signature .getInstance(SIGN_ALGORITHMS); signature.initVerify(pubKey); signature.update( content.getBytes(encode) ); boolean bverify = signature.verify( Base64.decode(sign) ); return bverify; } catch (Exception e) { e.printStackTrace(); } return false; } public static boolean doCheck(String content, String sign, String publicKey) { try { KeyFactory keyFactory = KeyFactory.getInstance('RSA'); byte[] encodedKey = Base64.decode(publicKey); PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey)); java.security.Signature signature = java.security.Signature .getInstance(SIGN_ALGORITHMS); signature.initVerify(pubKey); signature.update( content.getBytes() ); boolean bverify = signature.verify( Base64.decode(sign) ); return bverify; } catch (Exception e) { e.printStackTrace(); } return false; } } 測試代碼如下(需要添加commons-codec.jar依賴): public class MainTest { public static void main(String[] args) throws Exception { String filepath='d:/rsa/'; System.out.println('--------------公鑰加密私鑰解密過程-------------------'); String plainText='ihep_公鑰加密私鑰解密'; //公鑰加密過程 byte[] cipherData=RSAEncrypt.encrypt(RSAEncrypt.loadPublicKeyByStr(RSAEncrypt.loadPublicKeyByFile(filepath)),plainText.getBytes()); String cipher=Base64.encode(cipherData); //私鑰解密過程 byte[] res=RSAEncrypt.decrypt(RSAEncrypt.loadPrivateKeyByStr(RSAEncrypt.loadPrivateKeyByFile(filepath)), Base64.decode(cipher)); String restr=new String(res); System.out.println('原文:'+plainText); System.out.println('加密:'+cipher); System.out.println('解密:'+restr); System.out.println(); System.out.println('--------------私鑰加密公鑰解密過程-------------------'); plainText='ihep_私鑰加密公鑰解密'; //私鑰加密過程 cipherData=RSAEncrypt.encrypt(RSAEncrypt.loadPrivateKeyByStr(RSAEncrypt.loadPrivateKeyByFile(filepath)),plainText.getBytes()); cipher=Base64.encode(cipherData); //公鑰解密過程 res=RSAEncrypt.decrypt(RSAEncrypt.loadPublicKeyByStr(RSAEncrypt.loadPublicKeyByFile(filepath)), Base64.decode(cipher)); restr=new String(res); System.out.println('原文:'+plainText); System.out.println('加密:'+cipher); System.out.println('解密:'+restr); System.out.println(); System.out.println('---------------私鑰簽名過程------------------'); String content='ihep_這是用于簽名的原始數(shù)據(jù)'; String signstr=RSASignature.sign(content,RSAEncrypt.loadPrivateKeyByFile(filepath)); System.out.println('簽名原串:'+content); System.out.println('簽名串:'+signstr); System.out.println(); System.out.println('---------------公鑰校驗簽名------------------'); System.out.println('簽名原串:'+content); System.out.println('簽名串:'+signstr); System.out.println('驗簽結(jié)果:'+RSASignature.doCheck(content, signstr, RSAEncrypt.loadPublicKeyByFile(filepath))); System.out.println(); } } 該工具類代碼,可以結(jié)合MD5等算法混合使用,實現(xiàn)多重加密效果,有效保護數(shù)據(jù)安全 |
|
來自: 太極混元天尊 > 《學(xué)習(xí)資料》