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

  · 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已经做了简单测试,可以直接使用。

猜你喜欢

转载自blog.csdn.net/securitit/article/details/107591236