代码

/**
 * 3DES加解密
 */
public class DESedeUtils {
    private static final String ALGORITHM_MD5 = "md5";
    private static final String ALGORITHM_DESEDE = "DESede";//加密算法,可用 DES,DESede,Blowfish
    private static final String CHARSET = "UTF-8";

    public static void main(String[] args) throws Exception {
        byte[] key = get3DESKeyBytes("123456");
        byte[] source = "12345678".getBytes(CHARSET);
        byte[] source1 = "0123456789123456".getBytes(CHARSET);
        byte[] source2 = "1".getBytes(CHARSET);
        test(source, key);
        test(source1, key);
        test(source2, key);
    }

    private static void test(byte[] source, byte[] key) throws Exception {
        //生成的密文
        byte[] cryptograph = encryptOrDecrypt(source, key, Cipher.ENCRYPT_MODE);
        //通过Base64编码为ASCII字符后传输
        String cryptographStr = Base64.getEncoder().encodeToString(cryptograph);
        //收到后先用Base64解码
        byte[] targetBase64 = Base64.getDecoder().decode(cryptographStr.getBytes(CHARSET));
        // 解密密文
        byte[] target = encryptOrDecrypt(targetBase64, key, Cipher.DECRYPT_MODE);
        System.out.println("加密前【" + new String(source, CHARSET) + "】\n加密后【" + cryptographStr + "】\n解密后【" + new String(target, CHARSET) + "】");
        System.out.println("加密前字节数【" + source.length + "】加密后字节数【" + cryptograph.length + "】解密后字节数【" + target.length + "】\n");
    }

    /**
     * 加密或解密。加密和解密用的同一个算法和密钥
     * @param src    要加密或解密的数据
     * @param key    密钥
     * @param mode        加密或解密模式。值请选择Cipher.DECRYPT_MODE或Cipher.ENCRYPT_MODE
     * @return         加密或解密后的数据
     */
    public static byte[] encryptOrDecrypt(byte[] src, byte[] key, int mode) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM_DESEDE); //负责加密/解密的Cipher工具类
        Key key3DES = new SecretKeySpec(key, ALGORITHM_DESEDE); //3DES密钥
        cipher.init(mode, key3DES); //加密模式
        return cipher.doFinal(src);//按单部分操作加密或解密数据,或者结束一个多部分操作。返回:包含结果的新缓冲区 
    }

    /**
     * 根据字符串生成3DES的密钥字节数组<br>
     * 注意java的3des为24位密钥(24*8=192bit),c代码的话只要16位(16*8=128bit)
     */
    public static byte[] get3DESKeyBytes(String sKey) throws Exception {
        //获得指定摘要算法的 MessageDigest 对象
        MessageDigest md = MessageDigest.getInstance(ALGORITHM_MD5);
        //使用指定的字节更新摘要(继续多部分加密或解密操作,以处理其他数据部分)
        md.update(sKey.getBytes(CHARSET));
        //获得密文。注意:长度为16而不是32。一个字节(byte)占8位(bit)
        byte[] digestOfPassword = md.digest();
        //将16位消息摘要数组中的内容,拷贝到一个长度为【24】的数组中
        byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
        //再用前8位数据对应补全后8位
        for (int j = 0, k = 16; j < 8;) {
            keyBytes[k++] = keyBytes[j++];
        }
        return keyBytes;
    }

}


结果

加密前【12345678】
加密后【CS4ct3yhhJUnQXsmJGodZQ==】
解密后【12345678】
加密前字节数【8】加密后字节数【16】解密后字节数【8】

加密前【0123456789123456】
加密后【nZswcCGGA2sDye/3Ad6/BCdBeyYkah1l】
解密后【0123456789123456】
加密前字节数【16】加密后字节数【24】解密后字节数【16】

加密前【1】
加密后【p9itKXB92d0=】
解密后【1】

加密前字节数【1】加密后字节数【8】解密后字节数【1】


解疑:两张生成Key的方式

public class Test {
    private static final String ALGORITHM_DESEDE = "DESede";//加密算法,可用 DES,DESede(即3DES),Blowfish
    private static final String CHARSET = "UTF-8";
    public static void main(String[] args) throws Exception {
        //用来加密的字符串
        byte[] keyBytes = "012345678901234567890123".getBytes(CHARSET);//java的3DES为24位密钥
        //第一种产生Key的方式:根据提供的密钥规范生成一个密钥工厂,通过此密钥工厂根据指定的字节数组构造一个 SecretKey(只能对对称密钥进行操作)
        Key key1 = SecretKeyFactory.getInstance(ALGORITHM_DESEDE).generateSecret(new DESedeKeySpec(keyBytes));//相关类都在【javax.crypto.spec】包下
        //第二种产生Key的方式:直接根据指定的字节数组构造一个符合指定密钥规范的 SecretKey,而无须通过一个(基于 provider 的)SecretKeyFactory
        Key key2 = new SecretKeySpec(keyBytes, ALGORITHM_DESEDE);
        System.out.println(Arrays.toString(key1.getEncoded()) + "\n" + Arrays.toString(key2.getEncoded()) + "\n");
        byte[] source1 = "12345678".getBytes(CHARSET);
        byte[] source2 = "虽然两个Key并不相同,但是却可以用一个加密用另一个解密,谁能告诉我为什么?".getBytes(CHARSET);
        test(source1, key1, key2);
        test(source2, key2, key1);
    }
    private static void test(byte[] source, Key key1, Key key2) throws Exception {
        //用第一个Key生成密文
        byte[] cryptograph = encryptOrDecrypt(source, key1, Cipher.ENCRYPT_MODE);
        //通过Base64编码为ASCII字符后传输
        String cryptographStr = Base64.getEncoder().encodeToString(cryptograph);
        //收到后先用Base64解码
        byte[] targetBase64 = Base64.getDecoder().decode(cryptographStr.getBytes(CHARSET));
        //用第二个Key 解密密文
        byte[] target = encryptOrDecrypt(targetBase64, key2, Cipher.DECRYPT_MODE);
        System.out.println("加密前【" + new String(source, CHARSET) + "】\n加密后【" + cryptographStr + "】\n解密后【" + new String(target, CHARSET) + "】\n");
    }
    /**
     * 加密或解密。加密和解密用的同一个算法和密钥
     * @param src    要加密或解密的数据
     * @param key3DES    密钥
     * @param mode        加密或解密模式。值请选择Cipher.DECRYPT_MODE或Cipher.ENCRYPT_MODE
     * @return         加密或解密后的数据
     */
    public static byte[] encryptOrDecrypt(byte[] src, Key key3DES, int mode) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM_DESEDE); //负责加密/解密的Cipher工具类
        cipher.init(mode, key3DES); //加密模式
        return cipher.doFinal(src);//按单部分操作加密或解密数据,或者结束一个多部分操作。返回:包含结果的新缓冲区 
    }

}


结果

[49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 49, 49, 50, 50]
[48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 49, 50, 51]

加密前【12345678】
加密后【JHkgWn5or6kghB7oq65OZQ==】
解密后【12345678】

加密前【虽然两个Key并不相同,但是却可以用一个加密用另一个解密,谁能告诉我为什么?】
加密后【GfBN4sqbEb0WQ3tIUE+7L47WNDTUc+ZHphOC8qWbb5EozifxYNHENpEP09a1t9cq+x/s+NCcBqED4WuTgY2JeGGW/DuMJayKZ31SbmvoVHrFRsQpA7dQ51eZ1XOefcX8ElepTc52UFQ2FR/+3D4Gug==】

解密后【虽然两个Key并不相同,但是却可以用一个加密用另一个解密,谁能告诉我为什么?】

3DES加解密【示例】的更多相关文章

  1. 3DES 加解密

    using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace Comm ...

  2. PHP版3DES加解密类

    <?php /** * * PHP版3DES加解密类 * * 可与java的3DES(DESede)加密方式兼容 * * @Author:蓝凤(ilanfeng.com) * * @versio ...

  3. 3DES加解密 C语言

    3DES(或称为Triple DES),它相当于是对每个数据块应用三次DES加密算法.3*8字节密钥. 设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,P代表明文,C代 ...

  4. java 与 c# 3des 加解密

    java 与 c# 3des 加解密   主要差异如下: 1.  对于待加密解密的数据,各自的填充模式不一样 C#的模式有:ANSIX923.ISO10126.None.PKCS7.Zero,而Jav ...

  5. 3DES加解密类

    using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace GT.C ...

  6. PHP和.NET通用的加密解密函数类,均使用3DES加解密 .

    以下为php代码 <PRE class=PHP name="code"> </PRE><PRE class=PHP name="code&q ...

  7. 3des加解密算法

    编号:1003时间:2016年4月1日09:51:11功能:openssl_3des加解密算法http://blog.csdn.net/alonesword/article/details/17385 ...

  8. Java、C#双语版配套AES加解密示例

      这年头找个正经能用的东西那是真难,网上一搜索一大堆,正经能用的没几个,得,最后还是得靠自己,正巧遇上需要AES加解密的地方了,而且还是Java和C#间的相互加解密操作,这里做个备忘 这里采用的加解 ...

  9. 转载:Java、C#双语版配套AES加解密示例

    转载,原文出处 http://www.cnblogs.com/lzrabbit/p/3639503.html 这年头找个正经能用的东西那是真难,网上一搜索一大堆,正经能用的没几个,得,最后还是得靠自己 ...

随机推荐

  1. svn删除目录后提交显示Item 'XXXX' is out of date解决方法

    1.在要删除的目录上执行 svn 的 Delete 2.来到要删除目录的上级目录,执行更新操作.  3.找到要删除的目录,会显示冲突状态,在这个目录上执行Resolved.  4.在这个要删除的目录上 ...

  2. kernel 校验和实现

    kernel 校验和实现 Kernel checksum implementation ) TCP包的错误检测使用16位累加和校验. 除了TCP包本身, TCP校验数据块还包括源IP地址,目的IP地址 ...

  3. 【HDOJ】2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活

    多重背包. #include <stdio.h> #include <string.h> ]; int n, m; void completePac(int p, int h) ...

  4. zedGraph

    “zedGraph”控件画图的时候遇到了一点小问题,就是在同一个控件实例上第一次绘制饼图的时候一切正常,但是再次绘制的时候不是重新绘制新的饼图,而是在原有基础之上又添加进新的对象(PieItem),又 ...

  5. 算法 python实现(一) 基本常识

    我算法和数据结构都不好,笨的一比. 现在的目标是熟悉常见和经典算法,看本站两个大牛的博客,在这也推荐一下,特别好,除了算法其他的技术也很不错. Vamei : http://www.cnblogs.c ...

  6. FireMonkey隐藏任务栏图标

    FMX(FireMonkey)可以轻松实现很多VCL无法或难以实现的特效,所以将FMX程序作为界面,打包入DLL由VCL程序调用,是一个不错的方案.为了程序的完整性,你不想看见FMX程序在任务栏上显示 ...

  7. 洛谷1439 排列LCS问题

    洛谷1439 排列LCS问题 本题地址:http://www.luogu.org/problem/show?pid=1439 题目描述 给出1-n的两个排列P1和P2,求它们的最长公共子序列. 输入输 ...

  8. JavaScript高级程序设计44.pdf

    unload事件 与load事件对应的是unload事件,这个事件在文档被完全卸载后触发,只要用户从一个页面切换到另一个页面,就会发生unload事件,最多的情况是清除引用,避免内存泄漏 与load事 ...

  9. E. Three States - Codeforces Round #327 (Div. 2) 590C States(广搜)

    题目大意:有一个M*N的矩阵,在这个矩阵里面有三个王国,编号分别是123,想知道这三个王国连接起来最少需要再修多少路. 分析:首先求出来每个王国到所有能够到达点至少需要修建多少路,然后枚举所有点求出来 ...

  10. 解决jquery animate({scrollTop$pos},500)与$(window).scroll方法冲突的问题

    当点击节点时 先移除$(window).on("scroll")监听事件 在animate动画结束之后再添加上 $('#J_tab li').on('click', functio ...