前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >进击微信小程序-Java版AES/CBC/PKCS7Padding加解密字符串

进击微信小程序-Java版AES/CBC/PKCS7Padding加解密字符串

作者头像
WindCoder
发布2018-09-20 15:56:54
2.2K0
发布2018-09-20 15:56:54
举报
文章被收录于专栏:WindCoderWindCoder

前言

进击微信小程序,最初找到腾讯云给的解决方案,无奈后端是node.js,而且才一开始配上去还不能用,之后仔细看readme,摸到它开源的Wafer,本来以为找到终极解决方案了,仔细看后,发现提供的java方面仅有业务服务器端的代码(要不要如此“歧视”= =),会话服务器只有一个php版的,信道服务。。就更不用说了。于是乎只能自己啃了。

正庆幸之前看过一点php基础,等走到加密解密那,满心欢喜的下载完实例代码,吃惊的发现里面居然有没有java(此时内心可谓是一群动物在奔腾)。但是在崩溃也得向前啊,于是只能默默忍受着十万点真实伤害去搜索相关的解密方式。万幸的是,终于找到了个类似的,接着对照wafer的php版七改八改,还真完成了。

到目前为止实现了java版会话服务器端的移植,至于信道服务,由于暂时接到新需求,无法继续探索,只好暂时作罢,待过段时间继续来过。至于放出的嘛。。暂时就只有这个解密代码,完整的java会话还是过段时间有心情再放出吧,反正这个有了,小伙伴们估计很快也能完成自己的,而且。。毕竟公司都没来得及用上呢(不服?来咬我呀= =)。

进击微信小程序-Java版AES/CBC/PKCS7Padding加解密字符串
进击微信小程序-Java版AES/CBC/PKCS7Padding加解密字符串

这么萌你真的忍心么= =

主体

所需依赖

只需要一个jar包

maven可直接使用

代码语言:javascript
复制
  <!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
    <dependency>
      <groupId>org.bouncycastle</groupId>
      <artifactId>bcprov-jdk15on</artifactId>
      <version>1.55</version>
    </dependency>

非maven,可直接下载

下载地址:http://www.bouncycastle.org/archive/139/bcprov-jdk16-139.jar

加解密类代码

代码语言:javascript
复制
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;

/**
 * Created by wind on 2016/12/24.
 */

/**
 *
 * @author ngh
 * AES128 算法
 *
 * CBC 模式
 *
 * PKCS7Padding 填充模式
 *
 * CBC模式需要添加一个参数iv--对称解密算法初始向量 iv
 *
 * 介于java 不支持PKCS7Padding,只支持PKCS5Padding 但是PKCS7Padding 和 PKCS5Padding 没有什么区别
 * 要实现在java端用PKCS7Padding填充,需要用到bouncycastle组件来实现
 */
public class Pkcs7Encoder {
    // 算法名称
    static  final String KEY_ALGORITHM = "AES";
    // 加解密算法/模式/填充方式
    static  final String algorithmStr = "AES/CBC/PKCS7Padding";
    private static Key key;
    private static Cipher cipher;
    boolean isInited = false;

    //默认对称解密算法初始向量 iv
    static byte[] iv = { 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38 };

    public static void init(byte[] keyBytes) {

        // 如果密钥不足16位,那么就补足.  这个if 中的内容很重要
        int base = 16;
        if (keyBytes.length % base != 0) {
            int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);
            byte[] temp = new byte[groups * base];
            Arrays.fill(temp, (byte) 0);
            System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
            keyBytes = temp;
        }
        // 初始化
        Security.addProvider(new BouncyCastleProvider());
        // 转化成JAVA的密钥格式
        key = new SecretKeySpec(keyBytes, KEY_ALGORITHM);
        try {
            // 初始化cipher
            cipher = Cipher.getInstance(algorithmStr, "BC");
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    /**
     * 加密方法
     *      --使用默认iv时
     * @param content
     *            要加密的字符串
     * @param keyBytes
     *            加密密钥
     * @return
     */
    public static byte[] encrypt(byte[] content, byte[] keyBytes) {
        byte[] encryptedText =  encryptOfDiyIV(content,keyBytes,iv);
        return encryptedText;
    }


    /**
     * 解密方法
     *      --使用默认iv时
     * @param encryptedData
     *            要解密的字符串
     * @param keyBytes
     *            解密密钥
     * @return
     */
    public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes) {
        byte[] encryptedText = decryptOfDiyIV(encryptedData,keyBytes,iv);
        return encryptedText;
    }
    /**
     * 加密方法
     *      ---自定义对称解密算法初始向量 iv
     * @param content
     *              要加密的字符串
     * @param keyBytes
     *              加密密钥
     * @param ivs
     *         自定义对称解密算法初始向量 iv
     * @return 加密的结果
     */
    public static byte[] encryptOfDiyIV(byte[] content, byte[] keyBytes, byte[] ivs) {
        byte[] encryptedText = null;
        init(keyBytes);
        System.out.println("IV:" + new String(ivs));
        try {
            cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(ivs));
            encryptedText = cipher.doFinal(content);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return encryptedText;
    }
    /**
     * 解密方法
     *
     * @param encryptedData
     *            要解密的字符串
     * @param keyBytes
     *            解密密钥
     * @param ivs
     *         自定义对称解密算法初始向量 iv
     * @return
     */
    public static byte[] decryptOfDiyIV(byte[] encryptedData, byte[] keyBytes,byte[] ivs) {
        byte[] encryptedText = null;
        init(keyBytes);
        System.out.println("IV:" + new String(ivs));
        try {
            cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(ivs));
            encryptedText = cipher.doFinal(encryptedData);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return encryptedText;
    }
}

测试结果

测试类中的Base64解码是将java8的Base64加解码封装了一下,请根据实际情况自行完成解码工作(解码的jar与方法太多了,就不在这统一了)。

测试类

测试类

代码语言:javascript
复制
public class Test {

    public static void main(String[] args) { 
        String  encryptedData = "CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZMQmRzooG2xrDcvSnxIMXFufNstNGTyaGS9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+3hVbJSRgv+4lGOETKUQz6OYStslQ142dNCuabNPGBzlooOmB231qMM85d2/fV6ChevvXvQP8Hkue1poOFtnEtpyxVLW1zAo6/1Xx1COxFvrc2d7UL/lmHInNlxuacJXwu0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn/Hz7saL8xz+W//FRAUid1OksQaQx4CMs8LOddcQhULW4ucetDf96JcR3g0gfRK4PC7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns/8wR2SiRS7MNACwTyrGvt9ts8p12PKFdlqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYVoKlaRv85IfVunYzO0IKXsyl7JCUjCpoG20f0a04COwfneQAGGwd5oa+T8yO5hzuyDb/XcxxmK01EpqOyuxINew==";
        String iv="r7BXXKkLb8qrSNn05n0qiA==";
        String appid = "wx4f4bc4dec97d474b";
        String sessionKey = "tiihtNczf5v6AKRyjwEUhQ==";
        toStr(appid,sessionKey,encryptedData,iv);
    }

    private static void  toStr(String appid,String sessionKey,String  encryptedData ,String iv){
        byte[] sessionKeyBy = Base64Util.decode(sessionKey);
        byte[] encryptedDataBy = Base64Util.decode(encryptedData);
        byte[] ivBy = Base64Util.decode(iv);
        byte[] dec = Pkcs7Encoder.decryptOfDiyIV(encryptedDataBy, sessionKeyBy,ivBy);
        JSONObject h = new JSONObject(new String(dec));
        if(h.has("openId")){
            System.out.println("解密后的内容:" +h.toString() );
        }

    }

}
效果图
进击微信小程序-Java版AES/CBC/PKCS7Padding加解密字符串
进击微信小程序-Java版AES/CBC/PKCS7Padding加解密字符串

附录

参考资料

Java 使用AES/CBC/PKCS7Padding 加解密字符串

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-12-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 主体
    • 所需依赖
      • 加解密类代码
        • 测试结果
          • 测试类
          • 效果图
      • 附录
        • 参考资料
        相关产品与服务
        云开发 CloudBase
        云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档