当前位置: 代码迷 >> 综合 >> 解决AES报错javax.crypto.BadPaddingException: Given final block not properly padded.........问题
  详细解决方案

解决AES报错javax.crypto.BadPaddingException: Given final block not properly padded.........问题

热度:92   发布时间:2023-12-16 21:08:16.0

最近对接接口,加密方式选择了AES。本地测试都没问题,放到服务器上果然又不是那么顺利。。。。

AES解密遇到javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.

网上一顿百度,有说是jar问题的、有说是填充问题、有说是linux系统随机生成问题等等

慢慢一个个尝试,最终找到解决方法。

解决方法:

private String keyGeneratorES(String res,String algorithm,String key,int keysize,boolean isEncode){try {KeyGenerator kg = KeyGenerator.getInstance(algorithm);SecureRandom random = SecureRandom.getInstance(SIGN_ALGORITHMS);if (keysize == 0) {byte[] keyBytes = charset==null?key.getBytes():key.getBytes(charset);random.setSeed(keyBytes);kg.init(random);}else if (key==null) {kg.init(keysize);}else {byte[] keyBytes = charset==null?key.getBytes():key.getBytes(charset);random.setSeed(keyBytes);kg.init(keysize, random);}SecretKey sk = kg.generateKey();SecretKeySpec sks = new SecretKeySpec(sk.getEncoded(), algorithm);Cipher cipher = Cipher.getInstance(algorithm);if (isEncode) {cipher.init(Cipher.ENCRYPT_MODE, sks);byte[] resBytes = charset==null?res.getBytes():res.getBytes(charset);return parseByte2HexStr(cipher.doFinal(resBytes));}else {cipher.init(Cipher.DECRYPT_MODE, sks);return new String(cipher.doFinal(parseHexStr2Byte(res)));}} catch (Exception e) {e.printStackTrace();}return null;}

最后贴上工具类:

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.SecureRandom;public class EncryptUtil {public static final String MD5 = "MD5";public static final String SHA1 = "SHA1";public static final String HmacMD5 = "HmacMD5";public static final String HmacSHA1 = "HmacSHA1";public static final String DES = "DES";public static final String AES = "AES";/*** 	签名算法*/public static final String SIGN_ALGORITHMS = "SHA1PRNG"; /**编码格式;默认使用uft-8*/public String charset = "utf-8";/**DES*/public int keysizeDES = 0;/**AES*/public int keysizeAES = 128;public static EncryptUtil me;private EncryptUtil(){//单例}//双重锁public static EncryptUtil getInstance(){if (me==null) {synchronized (EncryptUtil.class) {if(me == null){me = new EncryptUtil();}}}return me;}/*** 使用MessageDigest进行单向加密(无密码)* @param res 被加密的文本* @param algorithm 加密算法名称* @return*/private String messageDigest(String res,String algorithm){try {MessageDigest md = MessageDigest.getInstance(algorithm);byte[] resBytes = charset==null?res.getBytes():res.getBytes(charset);return base64(md.digest(resBytes));} catch (Exception e) {e.printStackTrace();}return null;}/*** 使用KeyGenerator进行单向/双向加密(可设密码)* @param res 被加密的原文* @param algorithm  加密使用的算法名称* @param key 加密使用的秘钥* @return*/private String keyGeneratorMac(String res,String algorithm,String key){try {SecretKey sk = null;if (key==null) {KeyGenerator kg = KeyGenerator.getInstance(algorithm);sk = kg.generateKey();}else {byte[] keyBytes = charset==null?key.getBytes():key.getBytes(charset);sk = new SecretKeySpec(keyBytes, algorithm);}Mac mac = Mac.getInstance(algorithm);mac.init(sk);byte[] result = mac.doFinal(res.getBytes());return base64(result);} catch (Exception e) {e.printStackTrace();}return null;}/*** 使用KeyGenerator双向加密,DES/AES,注意这里转化为字符串的时候是将2进制转为16进制格式的字符串,不是直接转,因为会出错* @param res 加密的原文* @param algorithm 加密使用的算法名称* @param key  加密的秘钥* @param keysize* @param isEncode* @return*/private String keyGeneratorES(String res,String algorithm,String key,int keysize,boolean isEncode){try {KeyGenerator kg = KeyGenerator.getInstance(algorithm);SecureRandom random = SecureRandom.getInstance(SIGN_ALGORITHMS);if (keysize == 0) {byte[] keyBytes = charset==null?key.getBytes():key.getBytes(charset);random.setSeed(keyBytes);kg.init(random);}else if (key==null) {kg.init(keysize);}else {byte[] keyBytes = charset==null?key.getBytes():key.getBytes(charset);random.setSeed(keyBytes);kg.init(keysize, random);}SecretKey sk = kg.generateKey();SecretKeySpec sks = new SecretKeySpec(sk.getEncoded(), algorithm);Cipher cipher = Cipher.getInstance(algorithm);if (isEncode) {cipher.init(Cipher.ENCRYPT_MODE, sks);byte[] resBytes = charset==null?res.getBytes():res.getBytes(charset);return parseByte2HexStr(cipher.doFinal(resBytes));}else {cipher.init(Cipher.DECRYPT_MODE, sks);return new String(cipher.doFinal(parseHexStr2Byte(res)));}} catch (Exception e) {e.printStackTrace();}return null;}private String base64(byte[] res){return Base64.encode(res);}/**将二进制转换成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;}/*** md5加密算法进行加密(不可逆)* @param res 需要加密的原文* @return*/public String MD5(String res) {return messageDigest(res, MD5);}/*** md5加密算法进行加密(不可逆)* @param res  需要加密的原文* @param key  秘钥* @return*/public String MD5(String res, String key) {return keyGeneratorMac(res, HmacMD5, key);}/*** 使用SHA1加密算法进行加密(不可逆)* @param res 需要加密的原文* @return*/public String SHA1(String res) {return messageDigest(res, SHA1);}/*** 使用SHA1加密算法进行加密(不可逆)* @param res 需要加密的原文* @param key 秘钥* @return*/public String SHA1(String res, String key) {return keyGeneratorMac(res, HmacSHA1, key);}/*** 使用DES加密算法进行加密(可逆)* @param res 需要加密的原文* @param key 秘钥* @return*/public String DESencode(String res, String key) {return keyGeneratorES(res, DES, key, keysizeDES, true);}/*** 对使用DES加密算法的密文进行解密(可逆)* @param res 需要解密的密文* @param key 秘钥* @return*/public String DESdecode(String res, String key) {return keyGeneratorES(res, DES, key, keysizeDES, false);}/*** 使用AES加密算法经行加密(可逆)* @param res 需要加密的密文* @param key 秘钥* @return*/public String AESencode(String res, String key) {return keyGeneratorES(res, AES, key, keysizeAES, true);}/*** 对使用AES加密算法的密文进行解密* @param res 需要解密的密文* @param key 秘钥* @return*/public String AESdecode(String res, String key) {return keyGeneratorES(res, AES, key, keysizeAES, false);}/*** 使用异或进行加密* @param res 需要加密的密文* @param key 秘钥* @return*/public String XORencode(String res, String key) {byte[] bs = res.getBytes();for (int i = 0; i < bs.length; i++) {bs[i] = (byte) ((bs[i]) ^ key.hashCode());}return parseByte2HexStr(bs);}/*** 使用异或进行解密* @param res 需要解密的密文* @param key 秘钥* @return*/public String XORdecode(String res, String key) {byte[] bs = parseHexStr2Byte(res);for (int i = 0; i < bs.length; i++) {bs[i] = (byte) ((bs[i]) ^ key.hashCode());}return new String(bs);}/*** 直接使用异或(第一调用加密,第二次调用解密)* @param res 密文* @param key 秘钥* @return*/public int XOR(int res, String key) {return res ^ key.hashCode();}/*** 使用Base64进行加密* @param res 密文* @return*/public String Base64Encode(String res) {return Base64.encode(res.getBytes());}/*** 使用Base64进行解密* @param res* @return*/public String Base64Decode(String res) {return new String(Base64.decode(res));}
}

注:代码来自网络,忘记从哪获取的了,若有侵权,留言告知

  相关解决方案