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