記RSA非對稱加機密RSAUtil包分享
阿新 • • 發佈:2018-12-12
本類結合了網上各種資源整合而成,可以生產RSA金鑰對,解析公鑰私鑰,公鑰加解密,私鑰加解密。
RSAUtil.java
import java.security.InvalidKeyException; import java.security.InvalidParameterException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; import java.util.HashMap; import java.util.UUID; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; public class RSAUtil { public static final String ALGORITHM = "RSA"; public static final int KEY_SIZE = 1024; public static Base64.Decoder decoder = Base64.getDecoder(); public static Base64.Encoder encoder = Base64.getEncoder(); /** * 生成金鑰對 */ public static HashMap<String, String> generateKeyPair() throws Exception { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM); KeyPair keyPair; try { keyPairGenerator.initialize(KEY_SIZE, new SecureRandom(UUID.randomUUID().toString().replaceAll("-", "").getBytes())); keyPair = keyPairGenerator.generateKeyPair(); } catch (InvalidParameterException e) { throw e; } catch (NullPointerException e) { throw e; } RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); HashMap<String, String> map = new HashMap<String, String>(); map.put("private", encoder.encodeToString(rsaPrivateKey.getEncoded())); map.put("public", encoder.encodeToString(rsaPublicKey.getEncoded())); return map; } public static PublicKey getPublicKeyFromString(String key) throws NoSuchAlgorithmException, InvalidKeySpecException { // 取得公鑰 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(decoder.decode(key)); KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); PublicKey publicKey = keyFactory.generatePublic(x509KeySpec); return publicKey; } public static PrivateKey getPrivateKeyFromString(String key) throws NoSuchAlgorithmException, InvalidKeySpecException { // 取得私鑰 PKCS8EncodedKeySpec x509KeySpec = new PKCS8EncodedKeySpec(decoder.decode(key)); KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); PrivateKey privateKey = keyFactory.generatePrivate(x509KeySpec); return privateKey; } /** * RSA公鑰加密 * * @param content * 等待加密的資料 * @param publicKey * RSA 公鑰 if null then getPublicKey() * @return 加密後的密文(16進位制的字串) */ public static String encryptByPublic(byte[] content, PublicKey publicKey) { if (publicKey == null) { } try { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); // 該金鑰能夠加密的最大位元組長度 int splitLength = ((RSAPublicKey) publicKey).getModulus().bitLength() / 8 - 11; byte[][] arrays = splitBytes(content, splitLength); StringBuffer stringBuffer = new StringBuffer(); for (byte[] array : arrays) { stringBuffer.append(bytesToHexString(cipher.doFinal(array))); } return stringBuffer.toString(); } catch (NoSuchAlgorithmException e) { } catch (NoSuchPaddingException e) { } catch (InvalidKeyException e) { } catch (BadPaddingException e) { } catch (IllegalBlockSizeException e) { } return null; } /** * RSA私鑰加密 * * @param content * 等待加密的資料 * @param privateKey * RSA 私鑰 if null then getPrivateKey() * @return 加密後的密文(16進位制的字串) */ public static String encryptByPrivate(byte[] content, PrivateKey privateKey) { if (privateKey == null) { //privateKey = getPrivateKey(); } try { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, privateKey); // 該金鑰能夠加密的最大位元組長度 int splitLength = ((RSAPrivateKey) privateKey).getModulus().bitLength() / 8 - 11; byte[][] arrays = splitBytes(content, splitLength); StringBuffer stringBuffer = new StringBuffer(); for (byte[] array : arrays) { stringBuffer.append(bytesToHexString(cipher.doFinal(array))); } return stringBuffer.toString(); } catch (NoSuchAlgorithmException e) { } catch (NoSuchPaddingException e) { } catch (InvalidKeyException e) { } catch (BadPaddingException e) { } catch (IllegalBlockSizeException e) { } return null; } /** * RSA私鑰解密 * * @param content * 等待解密的資料 * @param privateKey * RSA 私鑰 if null then getPrivateKey() * @return 解密後的明文 */ public static String decryptByPrivate(String content, PrivateKey privateKey) { if (privateKey == null) { //privateKey = getPrivateKey(); } try { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); // 該金鑰能夠加密的最大位元組長度 int splitLength = ((RSAPrivateKey) privateKey).getModulus().bitLength() / 8; byte[] contentBytes = hexStringToBytes(content); byte[][] arrays = splitBytes(contentBytes, splitLength); StringBuffer stringBuffer = new StringBuffer(); for (byte[] array : arrays) { stringBuffer.append(new String(cipher.doFinal(array))); } return stringBuffer.toString(); } catch (NoSuchAlgorithmException e) { } catch (NoSuchPaddingException e) { } catch (InvalidKeyException e) { } catch (BadPaddingException e) { } catch (IllegalBlockSizeException e) { } return null; } /** * RSA公鑰解密 * * @param content * 等待解密的資料 * @param publicKey * RSA 公鑰 if null then getPublicKey() * @return 解密後的明文 */ public static String decryptByPublic(String content, PublicKey publicKey) { try { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, publicKey); // 該金鑰能夠加密的最大位元組長度 int splitLength = ((RSAPublicKey) publicKey).getModulus().bitLength() / 8; byte[] contentBytes = hexStringToBytes(content); byte[][] arrays = splitBytes(contentBytes, splitLength); StringBuffer stringBuffer = new StringBuffer(); for (byte[] array : arrays) { stringBuffer.append(new String(cipher.doFinal(array))); } return stringBuffer.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } return null; } /** * 根據限定的每組位元組長度,將位元組陣列分組 * * @param bytes * 等待分組的位元組組 * @param splitLength * 每組長度 * @return 分組後的位元組組 */ public static byte[][] splitBytes(byte[] bytes, int splitLength) { // bytes與splitLength的餘數 int remainder = bytes.length % splitLength; // 資料拆分後的組數,餘數不為0時加1 int quotient = remainder != 0 ? bytes.length / splitLength + 1 : bytes.length / splitLength; byte[][] arrays = new byte[quotient][]; byte[] array = null; for (int i = 0; i < quotient; i++) { // 如果是最後一組(quotient-1),同時餘數不等於0,就將最後一組設定為remainder的長度 if (i == quotient - 1 && remainder != 0) { array = new byte[remainder]; System.arraycopy(bytes, i * splitLength, array, 0, remainder); } else { array = new byte[splitLength]; System.arraycopy(bytes, i * splitLength, array, 0, splitLength); } arrays[i] = array; } return arrays; } /** * 將位元組陣列轉換成16進位制字串 * * @param bytes * 即將轉換的資料 * @return 16進位制字串 */ public static String bytesToHexString(byte[] bytes) { StringBuffer sb = new StringBuffer(bytes.length); String temp = null; for (int i = 0; i < bytes.length; i++) { temp = Integer.toHexString(0xFF & bytes[i]); if (temp.length() < 2) { sb.append(0); } sb.append(temp); } return sb.toString(); } /** * 將16進位制字串轉換成位元組陣列 * * @param hex * 16進位制字串 * @return byte[] */ public static byte[] hexStringToBytes(String hex) { int len = (hex.length() / 2); hex = hex.toUpperCase(); byte[] result = new byte[len]; char[] chars = hex.toCharArray(); for (int i = 0; i < len; i++) { int pos = i * 2; result[i] = (byte) (toByte(chars[pos]) << 4 | toByte(chars[pos + 1])); } return result; } /** * 將char轉換為byte * * @param c * char * @return byte */ private static byte toByte(char c) { return (byte) "0123456789ABCDEF".indexOf(c); } }
測試類:
import java.util.HashMap; public class TestRSA { /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { HashMap<String, String> map = RSAUtil.generateKeyPair(); String data = "dhkldfpaoidfpaidfpxxxx"; String result = RSAUtil.encryptByPrivate(data.getBytes(), RSAUtil.getPrivateKeyFromString(map.get("private"))); System.out.println(result); String reResult = RSAUtil.decryptByPublic(result, RSAUtil.getPublicKeyFromString(map.get("public"))); System.out.println(reResult); } }