微信小程序CryptoJS解析java DES/CBC/PKCS5Padding

2023-11-02

目标

java端采用DES/CBC/PKCS5Padding 加密,前端,小程序 js,如何进行加解密。

js解析库下载地址

原版下载地址

二次开发版本
我用的是二次开发版本.

解决代码

先给结果!如下代码是核心代码,如果看不懂,可以继续往下看 详细步骤解决

java后台端代码

DES/CBC/PKCS5Padding代码如下(写的一个简便的,直接粘贴到 java ide上可运行):

import com.sun.org.apache.xml.internal.security.utils.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class Des {
    public static void main(String[] args) {
       String result = encryptDES("123456","6eGicG6U");
       System.out.println(result);
    }

    /**
     * 加密 这个iv偏移量是数组!!
     */
    private static byte[] iv = {1, 2, 3, 4, 5, 6, 7, 8};

    public static String encryptDES(String encryptString, String encryptKey) {
        try {
            IvParameterSpec zeroIv = new IvParameterSpec(iv);
            SecretKeySpec key = new SecretKeySpec(encryptKey.getBytes(), "DES");
            System.out.println("key: "+encryptKey.getBytes().toString());
            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
            byte[] encryptedData = cipher.doFinal(encryptString.getBytes());
            return Base64.encode(encryptedData);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }

    }

    /**
     * 解密
     */
    public static String decryptDES(String decryptString, String decryptKey) {
        try {
            byte[] byteMi = Base64.decode(decryptString);
            IvParameterSpec zeroIv = new IvParameterSpec(iv);
            SecretKeySpec key = new SecretKeySpec(decryptKey.getBytes(), "DES");
            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);
            byte decryptedData[] = cipher.doFinal(byteMi);

            return new String(decryptedData);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
}

小程序 CryptoJS
//CBC模式加密  utf8 to base64
function encryptByDESModeCBCUtf8to64(message) {
  var key = '6eGicG6U'; //密钥
  var iv = [1, 2, 3, 4, 5, 6, 7, 8];
  var ivString = byteToString(iv)
  var keyHex = CryptoJS.enc.Utf8.parse(key);
  var ivHex = CryptoJS.enc.Utf8.parse(ivString);
  var encrypted = CryptoJS.DES.encrypt(message, keyHex, {
    iv: ivHex,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  })
  return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
}




function encryptByDESModeCBCUtf8to(message,key,iv) {
    var message=CryptoJS.enc.Utf8.parse(message);
var keyHex = CryptoJS.enc.Utf8.parse(key);
        var ivHex = CryptoJS.enc.Utf8.parse(iv);
        encrypted = CryptoJS.DES.encrypt(message, keyHex, {
iv:ivHex,
mode: CryptoJS.mode.CBC,
padding:CryptoJS.pad.Pkcs7
}
        );
        //加密 成Base64
return encrypted.ciphertext.toString();
// CryptoJS.enc.Base64
}

//CBC模式解密
function decryptByDESModeCBC(ciphertext2,key,iv) {
var keyHex = CryptoJS.enc.Utf8.parse(key);
        var ivHex = CryptoJS.enc.Utf8.parse(iv);
        // CryptoJS.enc.Base64.parse(
// direct decrypt ciphertext
var decrypted = CryptoJS.DES.decrypt({
 ciphertext: CryptoJS.enc.Base64.parse(ciphertext2)
}, keyHex, {
iv:ivHex,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}

//CBC模式解密
function decryptByDESModeCBCHex(ciphertext2,key,iv) {
var keyHex = CryptoJS.enc.Utf8.parse(key);
        var ivHex = CryptoJS.enc.Utf8.parse(iv);
// direct decrypt ciphertext
var decrypted = CryptoJS.DES.decrypt({
ciphertext: CryptoJS.enc.Hex.parse(ciphertext2)
}, keyHex, {
iv:ivHex,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});

return decrypted.toString(CryptoJS.enc.Utf8);
}

//DES  ECB模式加密
function encryptByDESModeEBC(message){
var keyHex = CryptoJS.enc.Utf8.parse(key);
var encrypted = CryptoJS.DES.encrypt(message, keyHex, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.ciphertext.toString();
}

//DES  ECB模式解密
function decryptByDESModeEBC(ciphertext){
var keyHex = CryptoJS.enc.Utf8.parse(key);
var decrypted = CryptoJS.DES.decrypt({
ciphertext: CryptoJS.enc.Hex.parse(ciphertext)
}, keyHex, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
var result_value = decrypted.toString(CryptoJS.enc.Utf8);
return result_value;
}
注意!!:

如果是java端 iv偏移量是数组,需要 js byte[] 和string 相互转换 UTF-8。

 function stringToByte(str) {
			var bytes = new Array();
			var len, c;
			len = str.length;
			for(var i = 0; i < len; i++) {
				c = str.charCodeAt(i);
				if(c >= 0x010000 && c <= 0x10FFFF) {
					bytes.push(((c >> 18) & 0x07) | 0xF0);
					bytes.push(((c >> 12) & 0x3F) | 0x80);
					bytes.push(((c >> 6) & 0x3F) | 0x80);
					bytes.push((c & 0x3F) | 0x80);
				} else if(c >= 0x000800 && c <= 0x00FFFF) {
					bytes.push(((c >> 12) & 0x0F) | 0xE0);
					bytes.push(((c >> 6) & 0x3F) | 0x80);
					bytes.push((c & 0x3F) | 0x80);
				} else if(c >= 0x000080 && c <= 0x0007FF) {
					bytes.push(((c >> 6) & 0x1F) | 0xC0);
					bytes.push((c & 0x3F) | 0x80);
				} else {
					bytes.push(c & 0xFF);
				}
			}
			return bytes;
		}
 
		 function byteToString(arr) {
			if(typeof arr === 'string') {
				return arr;
			}
			var str = '',
				_arr = arr;
			for(var i = 0; i < _arr.length; i++) {
				var one = _arr[i].toString(2),
					v = one.match(/^1+?(?=0)/);
				if(v && one.length == 8) {
					var bytesLength = v[0].length;
					var store = _arr[i].toString(2).slice(7 - bytesLength);
					for(var st = 1; st < bytesLength; st++) {
						store += _arr[st + i].toString(2).slice(2);
					}
					str += String.fromCharCode(parseInt(store, 2));
					i += bytesLength - 1;
				} else {
					str += String.fromCharCode(_arr[i]);
				}
			}
			return str;
		}

详细步骤解决

CryptoJs是google推出的一款前段解密类库.功能强大,包含很多的前段解密算法.
javascript解密库是用crypto-js。

小程序解决:

小程序需要引入CryptoJS github。

我用的是二次开发版本.

下载代码后:
将CryptoJS-master\rollups中的js添加到小程序中:
在这里插入图片描述
在 tripledes.js 下添加

module.exports = CryptoJS

在这里插入图片描述
在小程序中添加:

var CryptoJS = require('../../libs/CryptoJS/tripledes.js');

添加代码到页面。

//index.js
var CryptoJS = require('../../libs/CryptoJS/tripledes.js');
//获取应用实例
const app = getApp()
function byteToString(arr) {
  if (typeof arr === 'string') {
    return arr;
  }
  var str = '',
    _arr = arr;
  for (var i = 0; i < _arr.length; i++) {
    var one = _arr[i].toString(2),
      v = one.match(/^1+?(?=0)/);
    if (v && one.length == 8) {
      var bytesLength = v[0].length;
      var store = _arr[i].toString(2).slice(7 - bytesLength);
      for (var st = 1; st < bytesLength; st++) {
        store += _arr[st + i].toString(2).slice(2);
      }
      str += String.fromCharCode(parseInt(store, 2));
      i += bytesLength - 1;
    } else {
      str += String.fromCharCode(_arr[i]);
    }
  }
  return str;
}

function encryptByDESModeCBCUtf8to64(message) {
  var key = '6eGicG6U'; //密钥
  var iv = [1, 2, 3, 4, 5, 6, 7, 8];
  var ivString = byteToString(iv)
  var keyHex = CryptoJS.enc.Utf8.parse(key);
  var ivHex = CryptoJS.enc.Utf8.parse(ivString);
  var encrypted = CryptoJS.DES.encrypt(message, keyHex, {
    iv: ivHex,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  })
  return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
}

Page({
  data: {
    motto: 'Hello World',
    userInfo: {},
    hasUserInfo: false,
    canIUse: wx.canIUse('button.open-type.getUserInfo')
  },
  //事件处理函数
  bindViewTap: function() {
    wx.navigateTo({
      url: '../logs/logs'
    })
  },
  onLoad: function() {
    var encryptData = encryptByDESModeCBCUtf8to64("123456");
    console.log("encryptData " + encryptData);
  },

})

ok完成。

为什么添加上面的代码就可以解密?

首先准备一份明文和秘钥:

  var key = '6eGicG6U';  //一般key为一个字符串或者数组
  var iv = [1, 2, 3, 4, 5, 6, 7, 8];//偏移量

加密过程中使用哪种加密方式取决于传入key的类型,否则就会按照AES-256的方式加密。

Java就是按照128bit给的,需要使用CryptoJS.enc.Utf8.parse方法才可以将key转为128bit的。

// key 和 偏移量 用之前需要用uft8先parse一下才能用
var keyHex = CryptoJS.enc.Utf8.parse(key);
  var ivHex = CryptoJS.enc.Utf8.parse(ivString);

由于后端使用的是PKCS5Padding,CryptoJS的时候发现根本没有这个偏移。
但是Pkcs5是Pkcs7在块大小为8时特殊情况,本质上是一样的。Crypto-js默认padding是Pkcs7,可以直接使用。

  var encrypted = CryptoJS.DES.encrypt(message, keyHex, {
    iv: ivHex,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  })

由于CryptoJS生成的密文是一个对象,如果直接将其转为字符串是一个Base64编码过的,在encryptedData.ciphertext上的属性转为字符串才是后端需要的格式。
需要读取encryptedData上的ciphertext.toString()才能拿到跟Java一样的密文。

 return encrypted.ciphertext.toString(CryptoJS.enc.Base64);

到此,第一个方法讲解完了。

如果iv是byte数组,因为小程序 js无法表示byte需要将其转化方法。

function byteToString(arr) {...}

拓展

如果是AES只需使用CryptoJS.AES.encrypt,
需要引用的包改变一下,在aes.js中。

  var encrypted = CryptoJS.AES.encrypt(message, keyHex, {
    iv: ivHex,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  })

参考

一个在线加解密
如何使用CryptoJS的AES方法进行加密和解密
细说CryptoJs使用(微信小程序加密解密)

java端采用DES/CBC/PKCS5Padding 加密,js解密不了。google搜了好多方法没能解决

关于CryptoJS中md5加密以及aes加密的随笔

前端使用crypto.js进行加密
微信小程序des加密、PHP des解密

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

微信小程序CryptoJS解析java DES/CBC/PKCS5Padding 的相关文章

  • window.open()的替代方法

    window open 是被很多杀毒软件禁止的弹出框方式 所以可以采用form post的方式来打开 function OpenWindByPost window top location ctx page confirm confirmT

随机推荐

  • File类

    一 概述 1 File在包java io File下 代表系统的文件对象 文件 文件夹 File提供了诸如 定位文件获取文件本身的信息 删除文件 创建文件 文件夹 等功能 File创建对象有三种方法 第一种最为方便 其他两种只要没点大病都不
  • LeetCode 451. Sort Characters By Frequency

    原题网址 https leetcode com problems sort characters by frequency Given a string sort it in decreasing order based on the fr
  • Midjourney API 接口调试

    最近写了一个Midjourney API的接口 可以通过调用接口实现AI绘画 本地服务使用了 Midjourney 最近关注AI比较多 自己实现了一个AI绘画 Midjourney的接口 通过发送关键词就能实现绘画 发现需要的人也挺多的 准
  • JDK8主要新特性介绍(一)

    1 语言新特性1 1接口新增默认方法与静态方法 1 1 1 Interface Default Method For creating a default method in java interface we need to use de
  • DS18B20数字温度传感器

    DS18B20是一种数字温度传感器 由美国达拉斯半导体公司生产 具有以下特征 1 单线传输 DS18B20使用单线传输协议 1 Wire 进行通信 只需要一个数据线就可以实现数据传输和电源供应 2 高精度 DS18B20可以测量范围为 55
  • 五、高级数据结构和算法:2-3查找树、红黑树

    5 2 3查找树 红黑树 5 1 2 3查找树 和二叉树不一样 2 3树每个节点保存1个或者2个的key 对于普通的2节点 2 node 要有1个key和左右两个子节点 对应3节点 3 node 要有两个Key和三个子节点 2 3查找树的定
  • EMC测试(5)——传导发射测试(CE)

    1 1 概念介绍 传导发射 Conducted Emission 测试 简称CE 也被称为传导骚扰 是指系统内部的电压或电流通过信号电缆 电源线或地线传输出去而成为其他系统或设备干扰源的一种电磁现象 传导发射测试通常也会被称为骚扰电压测试
  • C# 多组充电测试框架

    有多个电流电压表通过串口连接到PC 点了对应按钮后 开始计时 到达对应时间后 读取电流电压表 链接 https caiyun 139 com m i 0E5CJYSahvlql 提取码 TDZa 复制内容打开和彩云手机APP 操作更方便哦
  • 小程序使用本地图片设置背景图

    如果在wxml文件中使用本地路径图片作为背景图 在微信开发者工具中可以显示出来 但运行到手机上显示不出来 解决如下 方法一 require 引入 使用 require 引入本地图片 require方式获取的值可以直接生成base64格式 d
  • 栈跟队列

    387 数据结构实验 顺序栈 描述创建一个顺序栈 能够完成栈的初始化 入栈 出栈 获取栈顶元素 销毁栈等操作
  • APT攻击详解

    0x01 APT到底是什么 APT 高级持续威胁 Advanced Persistent Threat 普遍认可的定义是 利用各种先进的攻击手段 对高价值目标进行的有组织 长期持续性网络攻击行为 也就是说很难去确定是不是APT攻击 只能从已
  • L1W2作业1

    1 使用numpy构建基本函数 Numpy是Python中主要的科学计算包 它由一个大型社区维护 在本练习中 你将学习一些关键的numpy函数 例如np exp np log和np reshape 你需要知道如何使用这些函数去完成将来的练习
  • Qt - MQTT客户端调试助手

    Qt MQTT客户端调试助手 Qt5 9 4 MinGW开发 MQTT调试助手 源码和软件下载链接如下 源码地址 https gitee com jhembedded MQTT Client 软件截图 使用说明 软件目录下有一个配置文件co
  • JavaWeb——Tomcat

    tomcat9安装步骤 Apache Tomcat Welcome 下载完 解压文件 测试tomcat是否能正常运行 启动tomca 打开网站输入localhost 8080 关闭tomcat tomca配置的核心文件server 可配置启
  • 高频卡S50和S70标签存储结构了解

    一 存储容量不同 Mifare S70的容量是S50的4倍 S50的容量是1K字节 S70的容量为4K字节 二 应答方式不同 二者应答读写器返回的卡类型 ATQA 字节不同 Mifare S50的卡类型 ATQA 是0004H Mifare
  • 快速创建一个servlet并且在web.xml配置和使用它

    这次 我要来教大家怎么快速创建一个servlet并且在web xml配置和使用它 实际上 现在可以直接在eclipse中创建一个servlet使其继承HttpServlet 而且你还可以对其进行一定的配置 在图中红色的地方写上你的Servl
  • Raneto中文搜索支持

    背景 因业务部门需要在线软件使用说明文档 但我们资源不足 故我想找一个开源的知识库 发现 Raneto不错 决定使用 官方文档相当清晰 部署完成 发布一些文章 启动项目 交由业务同事测试使用 于是我收到 中文搜索 不支持反馈 查看其配置文件
  • RocketMQ、RabbitMQ、Kafka区别

    一 编程语言 RocketMQ是java编写 Kafka采用scala RabbitMQ采用Erlang 二 数据权限安全 Kafka0 9 RocketMQ4 2以后 已经和RabbitMQ对齐 都有topic级别的控制权限 三 架构和高
  • 机器学习绪论(3)

    归纳偏好 机器学习算法在学习过程中对某种类型假设的偏好 归纳偏好对应了算法本身所做出的关于 什么样的模型更好 的假设 有效的机器学习算法必然有归纳偏好 否则无法产生确定的学习结果 比如对于下图 三个假设对于同一个新样本 会产生不同的结果 对
  • 微信小程序CryptoJS解析java DES/CBC/PKCS5Padding

    文章目录 目标 js解析库下载地址 解决代码 java后台端代码 小程序 CryptoJS 注意 详细步骤解决 小程序解决 为什么添加上面的代码就可以解密 拓展 参考 目标 java端采用DES CBC PKCS5Padding 加密 前端