java-信息安全(二)-对称加密算法DES,3DES,AES,Blowfish,RC2,RC4

概述

信息安全基本概念:

  • DES(Data Encryption Standard,数据加密标准)
  • 3DES(Triple DES,三重数据加密算法(TDEA,Triple Data Encryption Algorithm))
  • AES(Advanced Encryption Standard,高级加密标准)
  • Blowfish
  • RC2
  • RC4

DES

  DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。需要注意的是,在某些文献中,作为算法的DES称为数据加密算法(Data Encryption Algorithm,DEA),已与作为标准的DES区分开来。

  DES算法的入口参数有三个:Key、Data、Mode。其中Key为7个字节共56位,是DES算法的工作密钥;Data为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。

  DES设计中使用了分组密码设计的两个原则:混淆(confusion)和扩散(diffusion),其目的是抗击敌手对密码系统的统计分析。混淆是使密文的统计特性与密钥的取值之间的关系尽可能复杂化,以使密钥和明文以及密文之间的依赖性对密码分析者来说是无法利用的。扩散的作用就是将每一位明文的影响尽可能迅速地作用到较多的输出密文位中,以便在大量的密文中消除明文的统计结构,并且使每一位密钥的影响尽可能迅速地扩展到较多的密文位中,以防对密钥进行逐段破译。

3DES

  3DES又称Triple DES,是DES加密算法的一种模式,它使用3条56位的密钥对3DES.3DES数据进行三次加密。数据加密标准(DES)是美国的一种由来已久的加密标准,它使用对称密钥加密法,并于1981年被ANSI组织规范为ANSI X.3.92。DES使用56位密钥和密码块的方法,而在密码块的方法中,文本被分成64位大小的文本块然后再进行加密。比起最初的DES,3DES更为安全。
  3DES(即Triple DES)是DES向AES过渡的加密算法(1999年,NIST将3-DES指定为过渡的加密标准),加密算法,其具体实现如下:设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,M代表明文,C代表密文,这样:
    3DES加密过程为:C=Ek3(Dk2(Ek1(M)))
    3DES解密过程为:M=Dk1(EK2(Dk3(C)))

AES

  高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。

Blowfish

  Blowfish算法是一个64位分组及可变密钥长度的对称密钥分组密码算法,可用来加密64比特长度的字符串。

  Blowfish算法是一种对称的分组加密算法,算法核心在于子密钥生成,它将变长密钥扩展成总长4168 Byte的子密钥数组。算法中使用了大量的子密钥,而子密钥又依赖于用户密钥,实际加/解密过程中使用的是更新后的子密钥数组,子密钥即P数组和S盒。Blowfish算法有一个核心加密函数:BF_En(),该函数的输人是64位明文信息,经过运算,以64位密文信息的形式输出。用Blowfish算法加密信息,需要两个过程:密钥预处理和信息加密。同样,解密亦需要两个过程,密钥预处理和信息解密。  
  Blowfish算法的源密钥——pbox和sbox是固定的,而我们要加密一个信息,需要自己选择一个key,用这个key对pbox和sbox进行变换,得到下一步信息加密所要用的key_pbox和key_sbox。解密亦是如此,由于Blowfish是对称加密算法,解密方在得到key后根据key生成解密所需的key_box和key_sbox。对同一个信息加密解密,选取的key的不同会导致密文的不同。因此,Blowfish算法的关键在于key的选择以及保密。

RC2

  RC2是由著名密码学家Ron Rivest设计的一种传统对称分组加密算法,它可作为DES算法的建议替代算法。它的输入和输出都是64比特密钥的长度是从1字节到128字节可变,但目前的实现是8字节(1998年)

RC4

  RC4加密算法是大名鼎鼎的RSA三人组中的头号人物Ronald Rivest在1987年设计的密钥长度可变的流加密算法簇。之所以称其为簇,是由于其核心部分的S-box长度可为任意,但一般为256字节。该算法的速度可以达到DES加密的10倍左右,且具有很高级别的非线性。
 

示例代码

复制代码
package com.jd.order.util.encryption;

import java.security.Key;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;

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

/**
 * DESCoder帮助类
 * 
 * @author 木子旭
 * @since 2017年3月13日下午8:00:40
 * @version %I%,%G%
 */
public class DESCoder {
    /**
     * ALGORITHM 算法 <br>
     * 可替换为以下任意一种算法,同时key值的size相应改变。
     * 
     * <pre>
     * DES                  key size must be equal to 56 
     * DESede(TripleDES)    key size must be equal to 112 or 168 
     * AES                  key size must be equal to 128, 192 or 256,but 192 and 256 bits may not be available 
     * Blowfish             key size must be multiple of 8, and can only range from 32 to 448 (inclusive) 
     * RC2                  key size must be between 40 and 1024 bits 
     * RC4(ARCFOUR)         key size must be between 40 and 1024 bits
     * </pre>
     * 
     * 在Key toKey(byte[] key)方法中使用下述代码
     * <code>SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);</code> 替换
     * <code> 
     * DESKeySpec dks = new DESKeySpec(key); 
     * SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM); 
     * SecretKey secretKey = keyFactory.generateSecret(dks); 
     * </code>
     */
    public static String ALGORITHM = "DES";

    /**
     * 转换密钥<br>
     * 
     * @param key
     * @return
     * @throws Exception
     */
    private static Key toKey(byte[] key) throws Exception {
        SecretKey secretKey = null;
        if (ALGORITHM.equalsIgnoreCase("des")) {
            DESKeySpec dks = new DESKeySpec(key);
            SecretKeyFactory keyFactory = SecretKeyFactory
                    .getInstance(ALGORITHM);
            secretKey = keyFactory.generateSecret(dks);
        } else {
            // 当使用其他对称加密算法时,如AES、Blowfish等算法时,用下述代码替换上述三行代码
            secretKey = new SecretKeySpec(key, ALGORITHM);
        }
        return secretKey;
    }

    /**
     * 解密
     * 
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] decrypt(byte[] data, String key) throws Exception {
        Key k = toKey(decryptBASE64(key));
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, k);
        return cipher.doFinal(data);
    }

    /**
     * 加密
     * 
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] encrypt(byte[] data, String key) throws Exception {
        Key k = toKey(decryptBASE64(key));
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, k);
        return cipher.doFinal(data);
    }

    /**
     * 生成密钥
     * 
     * @return
     * @throws Exception
     */
    public static String initKey() throws Exception {
        return initKey(null);
    }

    /**
     * 生成密钥
     * 
     * @param seed
     * @return
     * @throws Exception
     */
    public static String initKey(String seed) throws Exception {
        SecureRandom secureRandom = null;
        if (seed != null) {
            secureRandom = new SecureRandom(decryptBASE64(seed));
        } else {
            secureRandom = new SecureRandom();
        }
        KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM);
        kg.init(secureRandom);
        SecretKey secretKey = kg.generateKey();
        return encryptBASE64(secretKey.getEncoded());
    }

    public static byte[] decryptBASE64(String data) {
        return Base64.decodeBase64(data);
    }

    public static String encryptBASE64(byte[] data) {
        return new String(Base64.encodeBase64(data));
    }
}
复制代码

测试:

复制代码
    @Test
    public void testEncrypt() throws Exception {
        String inputStr = "RC4";
        DESCoder.ALGORITHM = "RC4";
        String key = DESCoder.initKey();
        System.err.println("原文:\t" + inputStr);

        System.err.println("密钥:\t" + key);

        byte[] inputData = inputStr.getBytes();
        inputData = DESCoder.encrypt(inputData, key);

        System.err.println("加密后:\t" + DESCoder.encryptBASE64(inputData));

        byte[] outputData = DESCoder.decrypt(inputData, key);
        String outputStr = new String(outputData);

        System.err.println("解密后:\t" + outputStr);

        assertEquals(inputStr, outputStr);
    }
复制代码

输出

原文:    RC4
密钥:    3hrvT6h+2rBjlo9O9kWIuA==
加密后:    9/pU
解密后:    RC4

 

参看:

http://snowolf.iteye.com/blog/380034

百度百科等

posted @ 2017-12-08 11:04  暖阳g  阅读(1196)  评论(0编辑  收藏  举报