用户
 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,登录网站

2016-12-23 16:00:00 天下雪原创达人 造轮子 人生巅峰 楼主 344336
作者:百姓,来自蜂鸟社区
[AppleScript] 纯文本查看 复制代码
关键代码:
public String decrypt(String encryptedData, String sessionKey, String iv, String encodingFormat) throws Exception {
   try {
      Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
      BASE64Decoder base64Decoder = new BASE64Decoder();
      byte[] _encryptedData = base64Decoder.decodeBuffer(encryptedData);
      byte[] _sessionKey = base64Decoder.decodeBuffer(sessionKey);
      byte[] _iv = base64Decoder.decodeBuffer(iv);
      SecretKeySpec secretKeySpec = new SecretKeySpec(_sessionKey, "AES");
      IvParameterSpec ivParameterSpec = new IvParameterSpec(_iv);
      cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
      byte[] original = cipher.doFinal(_encryptedData);
      byte[] bytes = WxPKCS7Encoder.decode(original);
      String originalString = new String(bytes, encodingFormat);      return originalString;
   } catch (Exception ex) {
      return null;
   }
}
依赖类 WxPKCS7Encoder.javaclass WxPKCS7Encoder {
   static Charset CHARSET = Charset.forName("utf-8");
   static int BLOCK_SIZE = 32;

   /**
    * 获得对明文进行补位填充的字节.
    * 
    * @param count 需要进行填充补位操作的明文字节个数
    * @return 补齐用的字节数组
    */
   static byte[] encode(int count) {
      // 计算需要填充的位数
      int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
      if (amountToPad == 0) {
         amountToPad = BLOCK_SIZE;
      }
      // 获得补位所用的字符
      char padChr = chr(amountToPad);
      String tmp = new String();
      for (int index = 0; index < amountToPad; index++) {
         tmp += padChr;
      }
      return tmp.getBytes(CHARSET);
   }

   /**
    * 删除解密后明文的补位字符
    * 
    * @param decrypted 解密后的明文
    * @return 删除补位字符后的明文
    */
   static byte[] decode(byte[] decrypted) {
      int pad = (int) decrypted[decrypted.length - 1];
      if (pad < 1 || pad > 32) {
         pad = 0;
      }
      return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
   }

   /**
    * 将数字转化成ASCII码对应的字符,用于对明文进行补码
    * 
    * @param a 需要转化的数字
    * @return 转化得到的字符
    */
   static char chr(int a) {
      byte target = (byte) (a & 0xFF);
      return (char) target;
   }

}

jdk版本1.8

有问题请在本站内搜索相应关键词,假如无法解决请在综合交流区内发帖咨询,发帖时请提供详细的问题描述、相关图片及代码。
本帖最后由 forever4313 于 2017-1-21 11:54 编辑
天下雪 发表于 2017-1-13 11:24
作者   百姓    的回复   @forever4313

感谢,乱码我最终搞定了
参考如下:

AES.java
[Java] 纯文本查看 复制代码
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;

public class AES {
    public static boolean initialized = false;

    /**
     * AES解密
     * @param content 密文
     * @return
     * @throws InvalidAlgorithmParameterException
     * @throws NoSuchProviderException
     */
    public byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException {
        initialize();
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            Key sKeySpec = new SecretKeySpec(keyByte, "AES");

            cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    public static void initialize(){
        if (initialized) return;
        Security.addProvider(new BouncyCastleProvider());
        initialized = true;
    }
    //生成iv
    public static AlgorithmParameters generateIV(byte[] iv) throws Exception{
        AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
        params.init(new IvParameterSpec(iv));
        return params;
    }
}


WxPKCS7Encoder.java

[Java] 纯文本查看 复制代码
import java.nio.charset.Charset;
import java.util.Arrays;

/**
 * Created by Kevin Dong on 2017/1/5.
 */
public class WxPKCS7Encoder {

    private static final Charset CHARSET = Charset.forName("utf-8");
    private static final int BLOCK_SIZE = 32;

    /**
     * 获得对明文进行补位填充的字节.
     *
     * @param count 需要进行填充补位操作的明文字节个数
     * @return 补齐用的字节数组
     */
    public static byte[] encode(int count) {
        // 计算需要填充的位数
        int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
        if (amountToPad == 0) {
            amountToPad = BLOCK_SIZE;
        }
        // 获得补位所用的字符
        char padChr = chr(amountToPad);
        String tmp = new String();
        for (int index = 0; index < amountToPad; index++) {
            tmp += padChr;
        }
        return tmp.getBytes(CHARSET);
    }

    /**
     * 删除解密后明文的补位字符
     *
     * @param decrypted 解密后的明文
     * @return 删除补位字符后的明文
     */
    public static byte[] decode(byte[] decrypted) {
        int pad = decrypted[decrypted.length - 1];
        if (pad < 1 || pad > 32) {
            pad = 0;
        }
        return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
    }

    /**
     * 将数字转化成ASCII码对应的字符,用于对明文进行补码
     *
     * @param a 需要转化的数字
     * @return 转化得到的字符
     */
    public static char chr(int a) {
        byte target = (byte) (a & 0xFF);
        return (char) target;
    }
}


调用方法解密如下:

[Java] 纯文本查看 复制代码
WechatOpenIdRes wechatInfo  = getWehatInfoByCode(code);
        if(wechatInfo != null && wechatInfo.isOk()){
            boolean isNew = true;
            try {
                AES aes = new AES();
                byte[] resultByte = aes.decrypt(Base64.decodeBase64(encryptedData), Base64.decodeBase64(wechatInfo.getSession_key()), Base64.decodeBase64(iv));
                if(null != resultByte && resultByte.length > 0){
                    String userInfo = new String(WxPKCS7Encoder.decode(resultByte));
                    WxInfo wxInfo = GsonUtil.fromGson(userInfo, WxInfo.class);
                    if(wxInfo != null) {
                        logger.debug("xxxxxunionid===="+wxInfo.getUnionId());
                    }
                }
            } catch (InvalidAlgorithmParameterException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }


另外我引入的support 包为
bcprov-jdk16-139.jar  忘记是从哪个博客里看到,并下载的了,如果需要可以跟我联系。

只解密了部分,有部分是乱码。不知道为什么。
forever4313 发表于 2017-1-5 14:37
只解密了部分,有部分是乱码。不知道为什么。

把你解密后的问题描述一下,我让原作者帮忙看看
有问题请在本站内搜索相应关键词,假如无法解决请在综合交流区内发帖咨询,发帖时请提供详细的问题描述、相关图片及代码。
天下雪 发表于 2017-1-5 14:44
把你解密后的问题描述一下,我让原作者帮忙看看

密文发出来看看
有问题请在本站内搜索相应关键词,假如无法解决请在综合交流区内发帖咨询,发帖时请提供详细的问题描述、相关图片及代码。
天下雪 发表于 2017-1-5 14:44
把你解密后的问题描述一下,我让原作者帮忙看看

我的也是乱码哇
encryptedData:+T5jRPArykdjWn+84VznkBS8O8EgTMfONr5EKWTpOqtWTt4rankFwdiUC02sYWeFt/bJPEKfn2C4xmg8gKjvO8SKFYChawXYqiwvYrFJqxFiF4Lo5RdorM5aJ1A/vfr2cyGxrSFK+fg9XObzmWYSw1KTMkv3hpApe1+7wuIevsAhkx93ghzRhi0pP/TT+JRZoHaAJ9d+oLD/N2wBotRl9KekNW/ksovx6oSBjy5tqK46lLTT0OdaogXtcTKf9DY4kmqfw7JUT2wDcbF6O8KGGHoNCX8PpyuPO/xhQw5OOm03sUHbpeU2aBdW6auyESbCdQOu9e+hwY3jRMZJarUpnYDXAOh9P33SyKZAEL1wpZ3EaF44CD7jPZT4a65Eb5B1QFuzt2zwypKVK3CkmpKPZsEuaiNx38id6hnFYehJOCsYoREtxuqfAltYyu+FHarqeY/6YIK/eDBpK55lDZ7el9d6aMOxCX+dDrk17NxDQH7OQrqb2eiJRZandnpQHttdK2LvLShL6YciKqop5SFRmA==
iv:kOqT7mYiQk/KuEXFd8QBKQ==
sessionKey:ldaHDAt7+64cDniep4LEKg==

解密之后是乱码,楼主帮忙看看呢

密文发出来
有问题请在本站内搜索相应关键词,假如无法解决请在综合交流区内发帖咨询,发帖时请提供详细的问题描述、相关图片及代码。

encryptedData:+T5jRPArykdjWn+84VznkBS8O8EgTMfONr5EKWTpOqtWTt4rankFwdiUC02sYWeFt/bJPEKfn2C4xmg8gKjvO8SKFYChawXYqiwvYrFJqxFiF4Lo5RdorM5aJ1A/vfr2cyGxrSFK+fg9XObzmWYSw1KTMkv3hpApe1+7wuIevsAhkx93ghzRhi0pP/TT+JRZoHaAJ9d+oLD/N2wBotRl9KekNW/ksovx6oSBjy5tqK46lLTT0OdaogXtcTKf9DY4kmqfw7JUT2wDcbF6O8KGGHoNCX8PpyuPO/xhQw5OOm03sUHbpeU2aBdW6auyESbCdQOu9e+hwY3jRMZJarUpnYDXAOh9P33SyKZAEL1wpZ3EaF44CD7jPZT4a65Eb5B1QFuzt2zwypKVK3CkmpKPZsEuaiNx38id6hnFYehJOCsYoREtxuqfAltYyu+FHarqeY/6YIK/eDBpK55lDZ7el9d6aMOxCX+dDrk17NxDQH7OQrqb2eiJRZandnpQHttdK2LvLShL6YciKqop5SFRmA==
iv:kOqT7mYiQk/KuEXFd8QBKQ==
sessionKey:ldaHDAt7+64cDniep4LEKg==

楼主,怎么样啦

我让作者看看先   
有问题请在本站内搜索相应关键词,假如无法解决请在综合交流区内发帖咨询,发帖时请提供详细的问题描述、相关图片及代码。

作者   百姓    的回复   @forever4313
处理里面的 + 号
传递过去的时候,不然会失败
将 + 替换成 %2B

有问题请在本站内搜索相应关键词,假如无法解决请在综合交流区内发帖咨询,发帖时请提供详细的问题描述、相关图片及代码。
天下雪 发表于 2017-1-13 11:24
作者   百姓    的回复   @forever4313

我分别把encryptedData,session_key中的+号处理,也不对呢,楼主
runnerjiang 发表于 2017-1-13 11:40
我分别把encryptedData,session_key中的+号处理,也不对呢,楼主

先看看是否有其他需要处理的字符,都一并处理了试试先,不行,我再回问作者,毕竟老是耽误作者,不好意思啊
有问题请在本站内搜索相应关键词,假如无法解决请在综合交流区内发帖咨询,发帖时请提供详细的问题描述、相关图片及代码。
天下雪 发表于 2017-1-13 11:45
先看看是否有其他需要处理的字符,都一并处理了试试先,不行,我再回问作者,毕竟老是耽误作者 ...

字符经过encodeURIComponent处理还是失败
runnerjiang 发表于 2017-1-13 13:44
字符经过encodeURIComponent处理还是失败

我再问问。。。。
有问题请在本站内搜索相应关键词,假如无法解决请在综合交流区内发帖咨询,发帖时请提供详细的问题描述、相关图片及代码。
您需要登录后才可以回帖 登录 | 立即注册