一次采用commons-codec对明文进行加密的艰难之旅
背景:因为业务需要,需要对java工程,用到的配置文件的明文,进行加密。
在网上找到的通过的commons-codec-1.11-sources.jar的Base64类,进行加密解密
public class AESUtil {
private static String sKey = "XXX456AAAA4567239A222GF"; //密钥是string类型 长度是16、24、32
private static String ivParameter = sKey.substring(0, 16); ; //偏移量是密钥截取16位,也是string类型
public static String encrypt(String str) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] raw = sKey.getBytes(); // 密钥转成byte
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes()); //偏移量转成byte
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(str.getBytes(StandardCharsets.UTF_8));
return Base64.encodeBase64String(encrypted); //base64编码
} catch (Exception ex) {
return null;
}
}
public static String decrypt(String str) {
try {
byte[] raw = sKey.getBytes();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes()); //偏移量
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] encrypted1 = Base64.decodeBase64(str);
byte[] original = cipher.doFinal(encrypted1);
return new String(original, "utf-8");
} catch (Exception ex) {
return null;
}
}
}
刚开始,一切的都顺利,因为要对几个项目进行处理。前面的几个新项目,都是用maven进行打包。打包运行都没有问题。
问题:后面出现问题的,是一个通过原生的JDK进行打包,打包成可运行的jar包。这里就出现问题了。
运行时,没有问题。但是打包,通过命令行运行jar包的时候,出现了问题。报如下错误
Exception in thread "main" java.lang.NoSuchMethodError: org.apache.commons.codec.binary.Base64.decodeBase64(Ljava/lang/String;)[B
寻找解决方案:一致寻找解决方案,都找不到解决方案。网上该看的都看,自己该试的都试了
我通过反射,执行包的时候,命名可以找到类,并且对应的方法也是有的。
Base64.class = class org.apache.commons.codec.binary.Base64
methodName = decode
methodName = decode
methodName = encode
methodName = encode
methodName = decodeBase64
methodName = encodeBase64Chunked
methodName = isArrayByteBase64
methodName = encodeBase64
methodName = encodeBase64
methodName = wait
methodName = wait
methodName = wait
methodName = equals
methodName = toString
methodName = hashCode
methodName = getClass
methodName = notify
methodName = notifyAll
最后没办法,该找的方法都找。
解决方案:
只能抛弃commons-codec的Base64类了。
最终采纳了。java.util.Base64类方法。加密解密的算法的都是一样的。所以已加密的密文,不用换。
public class AESUtil {
private static String sKey = "0123456789ABCDEF0123456789ABCDEF"; //密钥是string类型 长度是16、24、32
private static String ivParameter = sKey.substring(0, 16); ; //偏移量是密钥截取16位,也是string类型
public static String encrypt(String str) {
try {
Cipher cipher = Cipher.getInstance("XXX456AAAA4567239A222GF");
byte[] raw = sKey.getBytes(); // 密钥转成byte
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes()); //偏移量转成byte
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(str.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encrypted);
//return Base64.encodeBase64String(encrypted); //base64编码
} catch (Exception ex) {
return null;
}
}
public static String decrypt(String str) {
try {
byte[] raw = sKey.getBytes();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes()); //偏移量
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] encrypted1 = Base64.getDecoder().decode(str);
//byte[] encrypted1 = Base64.decodeBase64(str);
byte[] original = cipher.doFinal(encrypted1);
return new String(original, "utf-8");
} catch (Exception ex) {
return null;
}
}
}

浙公网安备 33010602011771号