微信退款回调加密串AES解析

直接上代码

import java.security.Security;  

import javax.crypto.Cipher;  
import javax.crypto.spec.SecretKeySpec;  
  
import org.bouncycastle.jce.provider.BouncyCastleProvider;  
  
public class Encrypt {  
  
    public static boolean initialized = false;  
      
    public static final String ALGORITHM = "AES/ECB/PKCS7Padding";  
      
    /** 
     * @param  String str  要被加密的字符串 
     * @param  byte[] key  加/解密要用的长度为32的字节数组(256位)密钥 
     * @return byte[]  加密后的字节数组 
     */  
    public static byte[] Aes256Encode(String str, byte[] key){  
        initialize();  
        byte[] result = null;  
        try{  
            Cipher cipher = Cipher.getInstance(ALGORITHM, "BC");  
            SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); //生成加密解密需要的Key  
            cipher.init(Cipher.ENCRYPT_MODE, keySpec);  
            result = cipher.doFinal(str.getBytes("UTF-8"));  
        }catch(Exception e){  
            e.printStackTrace();  
        }  
        return result;  
    }  
      
    /** 
     * @param  byte[] bytes  要被解密的字节数组 
     * @param  byte[] key    加/解密要用的长度为32的字节数组(256位)密钥 
     * @return String  解密后的字符串 
     */  
    public static String Aes256Decode(byte[] bytes, byte[] key){  
        initialize();  
        String result = null;  
        try{  
            Cipher cipher = Cipher.getInstance(ALGORITHM, "BC");  
            SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); //生成加密解密需要的Key  
            cipher.init(Cipher.DECRYPT_MODE, keySpec);  
            byte[] decoded = cipher.doFinal(bytes);  
            result = new String(decoded, "UTF-8");  
        }catch(Exception e){  
            e.printStackTrace();  
        }  
        return result;  
    }  
      
    public static void initialize(){  
        if (initialized) return;  
        Security.addProvider(new BouncyCastleProvider());  
        initialized = true;  
    }  
}  

测试调用的代码

public static void main(String[] args) throws Exception {
        String md5Key = MD5Util.MD5Encode("你的apikey", "UTF-8").toLowerCase();
        byte[] key = md5Key.getBytes();
         String a = "微信回调返回来的加密串,根据req_info取出的";
         byte[] b = Base64Util.decode(a);
        System.out.println(Encrypt.Aes256Decode(b, key));

     }

问题1:

  • 代码开头要先import Java Cryptography Extension (JCE)中的两个类——加/解密类Cipher和密钥类SecretKeySpec,以及BouncyCastle的一个开源加/解密类库中的加/解密算法提供者类BouncyCastleProvider。
    PC上的Java里面只有"AES/ECB/PKCS5Padding"算法,没有"AES/ECB/PKCS7Padding"算法。故需要引入BouncyCastle的库,并给Cipher.getInstance方法传入参数"BC"来指定Java使用这个库里的加/解密算法。BouncyCastle的加/解密类库的下载地址:http://www.bouncycastle.org/latest_releases.html
    也可以是使用maven

      org.bouncycastle
      bcprov-jdk16
      1.45

问题2:

  • 用AES解密时出现"java.security.InvalidKeyException: Illegal key size"异常。
    如果密钥大于128, 会抛出上述异常。因为密钥长度是受限制的, java运行时环境读到的是受限的policy文件,文件位于/jre/lib/security下, 这种限制是因为美国对软件出口的控制。

  • 解决办法也很简单:
    jdk对应jar包的路径:D:\Java\jdk1.7.0_25\jre\lib\security
    jre对应jar包的路径:D:\Java\jre7\lib\security

jdk 5: http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-plat-419418.html#jce_policy-1.5.0-oth-JPR

jdk6: http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
JDK7的下载地址: http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
JDK8的下载地址: http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt
如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件
如果安装了JDK,还要将两个jar文件也放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件

你可能感兴趣的:(微信退款回调加密串AES解析)