欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

对称加密算法之Java 3DES算法应用

程序员文章站 2022-03-12 20:58:03
...

  · 3DES算法简介

  3DES又称Triple DES,是DES加密算法的一种模式,它使用两条不同的56位**对数据进行三次加密。

  DES使用56位**和密码块的方法,而在密码块的方法中,文本被分成64位大小的文本块然后再进行加密。相对DES,3DES更为安全。

  3DES是DES向AES过渡的加密算法,其具体实现如下:

  设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的**,M代表明文,C代表密文,这样:

    · 3DES加密过程为:C=Ek3(Dk2(Ek1(M)))。

    · 3DES解密过程为:M=Dk1(Ek2(Dk3©))。

  关于3DES概念性的内容不做过多介绍,大家可以自行百度。

  · Maven 依赖

  工具类对于加密后使用Base64进行编码,所以需要依赖Apache Commons Codec。

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.9</version>
</dependency>

  · 工具类实现

package com.arhorchin.securitit.enordecryption.des;

import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;

/**
 * @author Securitit.
 * @note 3DES加解密工具类.
 */
public class TripleDESUtil {

    /**
     * logger.
     */
    private static Logger logger = Logger.getLogger(TripleDESUtil.class);

    /**
     * 初始向量.
     */
    public static byte[] keyiv = { 1, 2, 3, 4, 5, 6, 7, 8 };

    /**
     * 字符串加密.
     * @param encodeStr.
     * @param desKey.
     * @return .
     */
    public static String strEncode(String encodeStr, String desKey) {
        try {
            byte[] key = Base64.decodeBase64(desKey);
            byte[] strData = encodeStr.getBytes("UTF-8");
            byte[] encodedStr = des3EncodeCBC(key, keyiv, strData);
            return Base64.encodeBase64String(encodedStr);
        } catch (Exception ex) {
            logger.error("TripleDESUtil.strEncode.", ex);
            return "";
        }
    }

    /**
     * 字符串解密.
     * @param decodeStr.
     * @param desKey.
     * @return .
     */
    public static String strDecode(String decodeStr, String desKey) {
        try {
            byte[] key = Base64.decodeBase64(desKey);
            byte[] decodedStr = Base64.decodeBase64(decodeStr);
            decodedStr = des3DecodeCBC(key, keyiv, decodedStr);
            String dcoding = new String(decodedStr, "UTF-8");
            return dcoding;
        } catch (Exception ex) {
            logger.error("TripleDESUtil.strDecode.", ex);
            return "";
        }
    }

    /**
     * 字符串加密.URL安全.
     * @param encodeStr.
     * @param desKey.
     * @return .
     */
    public static String strSafeEncode(String encodeStr, String desKey) {
        try {
            byte[] key = Base64.decodeBase64(desKey);
            byte[] strData = encodeStr.getBytes("UTF-8");
            byte[] encodedStr = des3EncodeCBC(key, keyiv, strData);
            return Base64.encodeBase64URLSafeString(encodedStr);
        } catch (Exception ex) {
            logger.error("TripleDESUtil.strSafeEncode.", ex);
            return "";
        }
    }

    /**
     * 字符串解密.URL安全.
     * @param decodeStr.
     * @param desKey.
     * @return .
     */
    public static String strSafeDecode(String decodeStr, String desKey) {
        try {
            byte[] key = Base64.decodeBase64(desKey);
            byte[] decodedStr = Base64.decodeBase64(decodeStr);
            decodedStr = des3DecodeCBC(key, keyiv, decodedStr);
            String dcoding = new String(decodedStr, "UTF-8");
            return dcoding;
        } catch (Exception ex) {
            logger.error("TripleDESUtil.strSafeDecode.", ex);
            return "";
        }
    }

    /**
     * 文件流解密.
     * @param srcBytes.
     * @param desKey.
     * @return .
     */
    public static byte[] byteEncode(byte[] srcBytes, String desKey) {
        try {
            byte[] key = Base64.decodeBase64(desKey);
            byte[] str5 = des3EncodeCBC(key, keyiv, srcBytes);
            return str5;
        } catch (Exception ex) {
            logger.error("TripleDESUtil.byteEncode.", ex);
            return null;
        }
    }

    /**
     * 文件流加密.
     * @param srcBytes.
     * @param desKey.
     * @return .
     */
    public static byte[] byteDecode(byte[] srcBytes, String desKey) {
        try {
            byte[] key = Base64.decodeBase64(desKey);
            byte[] str6 = des3DecodeCBC(key, keyiv, srcBytes);
            return str6;
        } catch (Exception ex) {
            logger.error("TripleDESUtil.byteDecode.", ex);
            return null;
        }
    }

    /**
     * 使用2DES加密数据.
     * @param key
     * @param keyiv.
     * @param data.
     * @return .
     * @throws Exception.
     */
    public static byte[] des3EncodeCBC(byte[] key, byte[] keyiv, byte[] data) throws Exception {
        Key deskey = null;
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
        deskey = keyfactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
        IvParameterSpec ips = new IvParameterSpec(keyiv);
        cipher.init(1, deskey, ips);
        byte[] bOut = cipher.doFinal(data);
        return bOut;
    }

    /**
     * 使用3DES解密数据.
     * @param key.
     * @param keyiv.
     * @param data.
     * @return .
     * @throws Exception.
     */
    public static byte[] des3DecodeCBC(byte[] key, byte[] keyiv, byte[] data) throws Exception {
        Key deskey = null;
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
        deskey = keyfactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
        IvParameterSpec ips = new IvParameterSpec(keyiv);
        cipher.init(2, deskey, ips);
        byte[] bOut = cipher.doFinal(data);
        return bOut;
    }

}

  · 测试类如下

package com.arhorchin.securitit.enordecryption.des;

import java.util.UUID;

/**
 * @author Securitit.
 * @note TripleDESUtil测试类.
 */
public class TripleDESUtilTester {

    public static void main(String[] args) {
        // 随机一个32位串作为秘钥.
        String desKey = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
        String plainText = "This is a 3des plain text";
        String cipherText = null;

        // 数据加密.
        cipherText = TripleDESUtil.strEncode(plainText, desKey);
        System.out.println("加密密文:" + cipherText);

        // 数据解密.
        plainText = TripleDESUtil.strDecode(cipherText, desKey);
        System.out.println("解密明文:" + plainText);
    }

}

  · 测试输出结果:

加密密文:kpEsLA2uoM74pUkTuDowUpvYQad9CrDsy1NGc3qL0VM=
解密明文:This is a 3des plain text

  · 总结:

  算法实现都很类似,本文只是对算法实现做了整理,在Maven依赖引入的情况下,TripleDESUtil已经做了简单测试,可以直接使用。