一次采用commons-codec对明文进行加密的艰难之旅

发布时间 2024-01-04 17:06:35作者: 信铁寒胜

背景:因为业务需要,需要对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;
        }
    }
}