js与java通用的3DES(ECB,CBC)+Base64加密编码,解码解密

J S端加密过程:
    key的处理:
通过创建指定的key,key必须是16位/24位/32位其中一种,但是常用的3DES加密的key为24位,下面使用的就是24位,key的长度可以随意指定,在转换key时,如果key不足24位则余数补0(因为最小位数必须是0以上),如果key多余24位,则会截取前24位数,多余部分则舍弃掉。

3DES加密的模式配定,有两种常见的加密方式:ECB和CBC模式

第一种:ECB(电子密本方式)其实非常简单,就是将数据按照8个字节一段进行DES加密或解密得到一段8个字节的密文或者明文,最后一段不足8个字节,按照需求补足8个字节进行计算,之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响。

第二种:CBC(密文分组链接方式)有点麻烦,它的实现机制使加密的各段数据之间有了联系。其实现的机理如下:
加密步骤如下:
(1)首先将数据按照8个字节一组进行分组得到D1D2......Dn(若数据不是8的整数倍,用指定的PADDING数据补位)
(2)第一组数据D1与初始化向量I异或后的结果进行DES加密得到第一组密文C1(初始化向量I为全零)
(3)第二组数据D2与第一组的加密结果C1异或以后的结果进行DES加密,得到第二组密文C2
(4)之后的数据以此类推,得到Cn
(5)按顺序连为C1C2C3......Cn即为加密结果。
解密是加密的逆过程,步骤如下:
(1)首先将数据按照8个字节一组进行分组得到C1C2C3......Cn
(2)将第一组数据进行解密后与初始化向量I进行异或得到第一组明文D1(注意:一定是先解密再异或)
(3)将第二组数据C2进行解密后与第一组密文数据进行异或得到第二组数据D2
(4)之后依此类推,得到Dn
(5)按顺序连为D1D2D3......Dn即为解密结果。
这里注意一点,解密的结果并不一定是我们原来的加密数据,可能还含有你补得位,一定要把补位去掉才是你的原来的数据。

以下是的JS端的Demo,通过3DES加密解密,Base64编码解码,需要引入JQuery框架和封装好的3DES加密解密算法,编码解码js文件:crypto-js.js,jsencrypt.js 这三个文件末尾处有链接下载。


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script  type="text/javascript" src="../js/jquery-2.2.3.min.js"  charset="UTF-8"></script>
    <script type="text/javascript"  src="../js/crypto-js.js" charset="UTF-8"></script>
    <script type="text/javascript"  src="../js/jsencrypt.js" charset="UTF-8"></script>
    <title>3DES加密解密与Base64编码解码处理数据</title>
    <style type="text/css">
        body {
            margin: 100px;
        }
        p, button {
            font-size: 30px;
        }
        .btn2 {
            margin-left: 100px;
        }
    </style>
    <script type="text/javascript">
        //秘钥key
        var key = "12345677654321";
        //key不足24位自动以0(最小位数是0)补齐,如果多余24位,则截取前24位,后面多余则舍弃掉
        var base64 = CryptoJS.enc.Utf8.parse(key)
        //加密使用的是3DES中的ECB,解密对应的使用ECB
        function encrypt() {
            var text = document.getElementById("content").innerText;
            var encrypt = CryptoJS.TripleDES.encrypt(text, base64, {
                    //iv: CryptoJS.enc.Utf8.parse('01234567'),//iv偏移量
                    //mode: CryptoJS.mode.CBC,  //CBC模式
                    mode: CryptoJS.mode.ECB,  //ECB模式
                    padding: CryptoJS.pad.Pkcs7//padding处理
                }
            );
            var encryptData = encrypt.toString();//加密完成后,转换成字符串
            document.getElementById("encrypt").innerText=encryptData;
        }
        //解密
        function decrypt() {
            var text = document.getElementById("encrypt").innerText;
            var decrypt = CryptoJS.TripleDES.decrypt(text, base64, {
                    //iv: CryptoJS.enc.Utf8.parse('01234567'),
                    //mode: CryptoJS.mode.CBC,
                    mode: CryptoJS.mode.ECB,
                    padding: CryptoJS.pad.Pkcs7
                }
            );
            //解析数据后转为UTF-8
            var parseData = decrypt.toString(CryptoJS.enc.Utf8);
            document.getElementById("decrypt").innerText=parseData;
        }
    </script>

</head>
<body>
        <h1>原文:</h1><p id="content">我是加密数据,点击下方加密按钮给我加密</p>
        <h1>加密编码后:</h1><p id="encrypt"></p>
        <h1>解码解密后:</h1><p id="decrypt"></p>
        <button οnclick="encrypt()">加密</button><button class="btn2" οnclick="decrypt()">解密</button>
</body>
</html>

Java端加密解密处理:
key的处理同上述一样,不足补0,多余则舍弃。为有不同的是:Java使用字符串DESede默认则是3DES加密,且模式使用的是ECB模式,PKCS5Padding ,系统默认配置后的全路径:DESede/ECB/PKCS5Padding,如果要使用CBC模式需要配置IV偏移量,指定全配置:DESede/CBC/PKCS5Padding,如若与JS端互相调用,则需要两端加密解密,编码解码的key,模式全部相同才可以解析出来。以下是ThreeDESUtils是Java端的加密解密,编码解码处理,注意顺序:
加密流程:3DES先加密,Base64再编码
解密流程:Base64先解码,3DES再解密
这里使用Base64编码是在android的环境下的,需要在android真机或模拟器上才能运行,如果在测试模式下,则会报错,后端则使用后端的编码处理。

import android.util.Base64;
import java.io.UnsupportedEncodingException;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
 * 3DES加密解密和BASE64编码解码混合使用
 */
public class ThreeDESUtils {

    //key必须在16位/24位/32位,下面使用的是24位,不足24位则后面余数补0填充满24位
    public static final String key="12345677654321";
    //定义加密算法,有DES、DESede(即3DES)、Blowfish
    private static final String Algorithm = "DESede";
    //如果使用DESede,默认则使用"DESede/ECB/PKCS5Padding"  ECB:电子密码本形式加密,
    // BCB:密码块链接加密
//    private static final String DES = "DESede/ECB/PKCS5Padding";
//    private static final String DES = "DESede/CBC/PKCS5Padding";
//    private static final String DES = "DESede/ECB/NoPadding";


    /**
     * 3DES加密方法
     * @param src 源数据的字节数组
     * @return
     */
    public static byte[] encryptMode(byte[] src,String key) {
        try {
            SecretKey deskey = new SecretKeySpec(build3DesKey(key), Algorithm);    //生成密钥
            Cipher c1 = Cipher.getInstance(Algorithm);    //实例化负责加密/解密的Cipher工具类
            c1.init(Cipher.ENCRYPT_MODE, deskey);    //初始化为加密模式
            return c1.doFinal(src);
        } catch (java.security.NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        } catch (javax.crypto.NoSuchPaddingException e2) {
            e2.printStackTrace();
        } catch (Exception e3) {
            e3.printStackTrace();
        }
        return null;
    }
    //3DES解密
    public static byte[] decrypt(byte[] data,String key){
        try {
            SecretKey deskey = new SecretKeySpec(build3DesKey(key), Algorithm);    //生成密钥
            Cipher cipher = Cipher.getInstance(Algorithm);
            cipher.init(Cipher.DECRYPT_MODE,deskey);
            return cipher.doFinal(data);
        } catch (Exception ex) {
            //解密失败,打日志
            ex.printStackTrace();
        }
        return null;
    }

    /**
     *  3DES加密Base64编码处理方法
     * @param bytes 字符串转的数组
     * @param key 用于3DES加密解密的密钥
     * @return  经过3DES+Base64加密后的字符串
     */
    public static String encode3DesBase64(byte[] bytes, String key){
        byte [] base = encryptMode(bytes,key);
        return  Base64.encodeToString(base,0);
    }

    /**
     * 将3DES+Base64加密后的byte数组进行解密
     * @param bytes 先3DES+Base64加密后的 byte数组
     * @param key  用于3DES加密解密的密钥
     * @return 未加密前的字符串
     */
    public static String decode3DesBase64(byte[] bytes, String key){
        byte[] b = null;
        String result = null;
        try {
            b = decrypt(Base64.decode(bytes,0),key);
            result = new String(b, "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    //构建3DES密钥
    public static byte[] build3DesKey(String keyStr) throws UnsupportedEncodingException {
        byte[] key = new byte[24];    //声明一个24位的字节数组,默认里面都是0
        byte[] temp = keyStr.getBytes("UTF-8");    //将字符串转成字节数组
         /*
          * 执行数组拷贝
          * System.arraycopy(源数组,从源数组哪里开始拷贝,目标数组,拷贝多少位)
          */
        if(key.length > temp.length){
            //如果temp不够24位,则拷贝temp数组整个长度的内容到key数组中
            System.arraycopy(temp, 0, key, 0, temp.length);
        }else{
            //如果temp大于24位,则拷贝temp数组24个长度的内容到key数组中
            System.arraycopy(temp, 0, key, 0, key.length);
        }
        return key;
    }
}
上面的Demo都是相通的,通过HTML里面的加密后的数据,java端可以解析出来,反之亦然。


JS端加密文件下载地址:https://download.csdn.net/download/bob_xing_yang/10431821


  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值