简介
非对称加密:加密和解密使用不同的秘钥的加解密方法。一般的,用公钥做加密,私钥做解密使用
常用的加解密有:RSA、ECC、DSA,在java中使用最多的是RSA
工具类
/*** 非对称加解密工具类(RSA)** RSA加密(一次)有最大字节数组限制 177、解密的最大字符限制128***/
public class AsymmetricEncryptDecryptionUtil {public static final String UTF8= StandardCharsets.UTF_8.name();public static final String ALGORITHM = "RSA";public static final int MAX_ENC_LENGTH = 117;public static final int MAX_DEN_LENGTH = 128;/*** 创建公钥和私钥对的16进制字符串** @throws NoSuchAlgorithmException 算法异常* @throws IOException io异常*/public static void createKeyPair() throws NoSuchAlgorithmException, IOException {KeyPairGenerator pairGenerator = KeyPairGenerator.getInstance(ALGORITHM);pairGenerator.initialize(1024);KeyPair keyPair = pairGenerator.genKeyPair();// 公钥PublicKey publicKey = keyPair.getPublic();// 私钥PrivateKey privateKey = keyPair.getPrivate();// 公钥秘钥字节数组byte[] publicKeyPairEncoded = publicKey.getEncoded();// 私钥秘钥字节数组byte[] privateKeyEncoded = privateKey.getEncoded();String pubHexStr = Hex.encodeHexString(publicKeyPairEncoded);String priHexStr = Hex.encodeHexString(privateKeyEncoded);System.out.println("公钥是:" + pubHexStr);System.out.println("私钥是:" + priHexStr);}private static PublicKey getPublicKey() throws Exception {String pubCfFile = AsymmetricEncryptDecryptionUtil.class.getClassLoader().getResource("rsa.pub").getPath();String pubKeyHexStr = FileUtils.readFileToString(new File(pubCfFile), UTF8);KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Hex.decodeHex(pubKeyHexStr));return keyFactory.generatePublic(x509EncodedKeySpec);}private static PrivateKey getPrivateKey() throws Exception {String priCfFile = AsymmetricEncryptDecryptionUtil.class.getClassLoader().getResource("rsa.pri").getPath();String priKeyHexStr = FileUtils.readFileToString(new File(priCfFile), UTF8);KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Hex.decodeHex(priKeyHexStr));return keyFactory.generatePrivate(pkcs8EncodedKeySpec);}public static String encodeStr(String originalStr,Key key) throws Exception {Cipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE,key);byte[] bytes = doCodec(cipher, originalStr.getBytes(UTF8), MAX_ENC_LENGTH);return Hex.encodeHexString(bytes);}public static String deCodeStr(String hexStr,Key key) throws Exception {byte[] bytes = Hex.decodeHex(hexStr);Cipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.DECRYPT_MODE,key);byte[] originalBytes = doCodec(cipher,bytes,MAX_DEN_LENGTH);return new String(originalBytes,UTF8);}/*** 由于RSA加密、解密都有最大字节数组长度限制(加密是177长度,解密是128长度)** 所以需要循环处理** @param cipher cipher* @param bytes 待加解密的字节数组* @param maxLength 处理的最大长度* @return 加解密的字节数组* @throws BadPaddingException BadPaddingException* @throws IllegalBlockSizeException IllegalBlockSizeException*/private static byte[] doCodec(Cipher cipher,byte[] bytes,int maxLength) throws BadPaddingException, IllegalBlockSizeException {int length = bytes.length;int offset = 0;byte[] cache;int i = 0;ByteArrayOutputStream bos = new ByteArrayOutputStream();while ((length - offset) > 0) {if(length - offset > maxLength) {cache = cipher.doFinal(bytes,offset,maxLength);} else {cache = cipher.doFinal(bytes,offset,length - offset);}i++;offset = i * maxLength;bos.write(cache,0,cache.length);}return bos.toByteArray();}public static void main(String[] args) throws Exception {String str = "法律";PublicKey publicKey = getPublicKey();String s = encodeStr(str, publicKey);System.out.println("RSA encode result:" + s);PrivateKey privateKey = getPrivateKey();String s1 = deCodeStr(s,privateKey);System.out.println("RSA decode result:" + s1);}
}
注意:RSA加解密有限制,一次加密的最大字节数组不能超过177长度,解密的最大数组长度不能超过128个字节长度