rsa默认最多只能加密密钥长度/8-11长度的明文,最多只能解密密钥长度/8长度的密文,如:
密钥长度为1024,则明文长度最长117,密文长度最长128。
可以采用分段加解密的方式,增加明文密文长度(同时加解密的效率也会按比例降低)。
工具类如下:
package com.kuandeng.common.common.util; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Base64; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import java.io.ByteArrayOutputStream; import java.nio.charset.StandardCharsets; import java.security.*; 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; @Slf4j public class RSACipher { public static String AlgorithmName = "RSA"; public static String Algorithm = "RSA/ECB/PKCS1Padding"; public static int KeyLength = 2048; private static int MAX_ENCRYPT_BLOCK = 117; private static int MAX_DECRYPT_BLOCK = 128; static { MAX_ENCRYPT_BLOCK = KeyLength/8 - 11; MAX_DECRYPT_BLOCK = KeyLength/8; } @Getter private String publicKey; @Getter private String privateKey; //公钥加密 private Cipher publicEncryptCipher = null; //私钥解密 private Cipher privateDecryptCipher = null; //私钥加密 private Cipher privateEncryptCipher = null; //公钥解密 private Cipher publicDecryptCipher = null; public RSACipher(String publicKey, String privateKey) { this.init(publicKey, privateKey); } public void init(String publicKey, String privateKey){ this.publicKey = publicKey; this.privateKey = privateKey; //公钥加密 byte[] decoded = Base64.decodeBase64(publicKey); RSAPublicKey pubKey = null; try { pubKey = (RSAPublicKey) KeyFactory.getInstance(AlgorithmName).generatePublic(new X509EncodedKeySpec(decoded)); // publicCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding"); publicEncryptCipher = Cipher.getInstance(Algorithm); publicEncryptCipher.init(Cipher.ENCRYPT_MODE, pubKey); } catch (InvalidKeySpecException | InvalidKeyException | NoSuchPaddingException | NoSuchAlgorithmException e) { log.warn(ExceptionHelper.getStackTraceString(e)); } //私钥解密 //64位解码加密后的字符串 //base64编码的私钥 byte[] decoded2 = Base64.decodeBase64(privateKey); RSAPrivateKey priKey = null; try { priKey = (RSAPrivateKey) KeyFactory.getInstance(AlgorithmName).generatePrivate(new PKCS8EncodedKeySpec(decoded2)); // privateCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding"); privateDecryptCipher = Cipher.getInstance(Algorithm); privateDecryptCipher.init(Cipher.DECRYPT_MODE, priKey); } catch (InvalidKeySpecException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException e) { log.warn(ExceptionHelper.getStackTraceString(e)); } //私钥加密 byte[] decoded3 = Base64.decodeBase64(privateKey); RSAPrivateKey pubKey2 = null; try { pubKey2 = (RSAPrivateKey) KeyFactory.getInstance(AlgorithmName).generatePrivate(new PKCS8EncodedKeySpec(decoded3)); // publicCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding"); privateEncryptCipher = Cipher.getInstance(Algorithm); privateEncryptCipher.init(Cipher.ENCRYPT_MODE, pubKey2); } catch (InvalidKeySpecException | InvalidKeyException | NoSuchPaddingException | NoSuchAlgorithmException e) { log.warn(ExceptionHelper.getStackTraceString(e)); } //公钥解密 //64位解码加密后的字符串 //base64编码的私钥 byte[] decoded23 = Base64.decodeBase64(publicKey); RSAPublicKey priKey2 = null; try { priKey2 = (RSAPublicKey) KeyFactory.getInstance(AlgorithmName).generatePublic(new X509EncodedKeySpec(decoded23)); // privateCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding"); publicDecryptCipher = Cipher.getInstance(Algorithm); publicDecryptCipher.init(Cipher.DECRYPT_MODE, priKey2); } catch (InvalidKeySpecException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException e) { log.warn(ExceptionHelper.getStackTraceString(e)); } } //随机生成密钥对 public static String[] genKeyPair() { // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象 KeyPairGenerator keyPairGen = null; try { keyPairGen = KeyPairGenerator.getInstance(AlgorithmName); } catch (NoSuchAlgorithmException e) { log.warn(ExceptionHelper.getStackTraceString(e)); } // 初始化密钥对生成器,密钥大小为96-1024位 assert keyPairGen != null; keyPairGen.initialize(KeyLength, new SecureRandom()); // 生成一个密钥对,保存在keyPair中 KeyPair keyPair = keyPairGen.generateKeyPair(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到私钥 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 得到公钥 String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded())); String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded()))); log.info("随机生成的公钥为:" + publicKeyString); log.info("随机生成的私钥为:" + privateKeyString); return new String[]{publicKeyString, privateKeyString}; } private byte[] crypt(byte[] data, Cipher cipher, int maxLength) { ByteArrayOutputStream out = new ByteArrayOutputStream(); int inputLen = data.length; int offSet = 0; byte[] cache; // 对数据分段解密 try { while (inputLen - offSet > 0) { if (inputLen - offSet > maxLength) { cache = cipher.doFinal(data, offSet, maxLength); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); offSet += maxLength; } return out.toByteArray(); } catch (BadPaddingException | IllegalBlockSizeException e) { log.warn(ExceptionHelper.getStackTraceString(e)); } finally { try{ out.close(); }catch (Exception e){ log.warn(ExceptionHelper.getStackTraceString(e)); } } return null; } /** * RSA分段加密 * * @param str 加密字符串 * @return 密文 */ private String encrypt(String str, Cipher cipher) { //只能处理MAX_ENCRYPT_BLOCK长度的数据,故用下面的代码改写 // try { // return Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8))); // } catch (IllegalBlockSizeException e) { // e.printStackTrace(); // } catch (BadPaddingException e) { // e.printStackTrace(); // } byte[] data = str.getBytes(StandardCharsets.UTF_8); return Base64.encodeBase64String(crypt(data, cipher, MAX_ENCRYPT_BLOCK)); } /** * RSA分段解密 * * @param str 加密字符串 * @return 明文 */ private String decrypt(String str, Cipher cipher) { //只能处理MAX_DECRYPT_BLOCK长度的数据,故用下面的代码改写 // byte[] data = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8)); // try { // return new String(privateDecryptCipher.doFinal(data)); // } catch (BadPaddingException | // IllegalBlockSizeException e) { // e.printStackTrace(); // } byte[] data = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8)); byte[] result = crypt(data, cipher, MAX_DECRYPT_BLOCK); if(result == null){ return null; } return new String(result, StandardCharsets.UTF_8); } /** * RSA公钥加密 * * @param str 加密字符串 * @return 密文 */ public String publicEncrypt(String str) { return encrypt(str, publicEncryptCipher); } /** * RSA私钥解密 * * @param str 加密字符串 * @return 明文 */ public String privateDecrypt(String str) { return decrypt(str, privateDecryptCipher); } /** * RSA私钥加密 * * @param str 加密字符串 * @return 密文 */ public String privateEncrypt(String str) { return encrypt(str, privateEncryptCipher); } /** * RSA公钥解密 * * @param str 加密字符串 * @return 明文 */ public String publicDecrypt(String str) { return decrypt(str, publicDecryptCipher); } }
标签:加密,String,过长,rsa,Cipher,str,import,return From: https://www.cnblogs.com/zycjwdss/p/18224847