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 这三个文件末尾处有链接下载。





    
    
    
    
    3DES加密解密与Base64编码解码处理数据
    
    



        

原文:

我是加密数据,点击下方加密按钮给我加密

加密编码后:

解码解密后:


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


你可能感兴趣的:(数据加密)