Java加密技术(二)对称加密算法DES&AES

   接下来我们介绍对称加密算法,最常用的莫过于DES数据加密算法。 
DES 
DES-Data Encryption Standard,即数据加密算法。是IBM公司于1975年研究成功并公开发表的。DES算法的入口参数有三个:Key、Data、Mode。其中Key为8个字节共64位,是DES算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。 
  DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位。 

技术分享 

通过java代码实现如下:

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.util.Arrays;

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;
import org.apache.commons.codec.binary.Hex;

/**对称加密算法DES&AES
 * @description: TODO 
 * @author Somnus
 * date 2015年4月8日 下午2:10:44  
 */
public class DESUtil {
    /** 
     * 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 keyGenerator(byte[] key)方法中使用下述代码 
     * <code>SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);</code> 替换 
     * <code> 
     * DESKeySpec desKey = new DESKeySpec(key); 
     * SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM); 
     * SecretKey secretKey = keyFactory.generateSecret(desKey); 
     * </code> 
     */
    public static final String ALGORITHM = "DES";
    //算法名称/加密模式/填充方式 
    //DES共有四种工作模式-->>ECB:电子密码本模式、CBC:加密分组链接模式、CFB:加密反馈模式、OFB:输出反馈模式
    public static final String CIPHER_ALGORITHM = "DES/ECB/NoPadding";

    /**
     *   
     * 生成密钥key对象
     * @param KeyStr 密钥字符串 
     * @return 密钥对象 
     * @throws InvalidKeyException   
     * @throws NoSuchAlgorithmException   
     * @throws InvalidKeySpecException   
     * @throws Exception 
     */
    private static SecretKey keyGenerator(byte[] key) throws Exception {
        DESKeySpec desKey = new DESKeySpec(key);
        //创建一个密匙工厂,然后用它把DESKeySpec转换成
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
        SecretKey securekey = keyFactory.generateSecret(desKey);
        
        /*当使用其他对称加密算法时,如AES、Blowfish等算法时,用下述代码替换上述三行代码 */
        /*SecretKey secretKey = new SecretKeySpec(keyStr.getBytes(),KEY_ALGORITHM);*/  
        return securekey;
    }

    /** 
     * 加密数据
     * @param data 待加密数据
     * @param key 密钥
     * @return 加密后的数据 
     */
    public static String encrypt(String data, String keyStr) throws Exception {
        Key deskey = keyGenerator(Base64.decodeBase64(keyStr));
        // 实例化Cipher对象,它用于完成实际的加密操作
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        // 初始化Cipher对象,设置为加密模式
        cipher.init(Cipher.ENCRYPT_MODE, deskey);
        byte[] buff = cipher.doFinal(data.getBytes());
        System.out.println(Arrays.toString(buff));
        // 执行加密操作。加密后的结果通常都会用Base64编码进行传输 
        return Hex.encodeHexString(buff);
    }

    /** 
     * 解密数据 
     * @param data 待解密数据 
     * @param key 密钥 
     * @return 解密后的数据 
     */
    public static String decrypt(String data, String keyStr) throws Exception {
        Key deskey = keyGenerator(Base64.decodeBase64(keyStr));
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        //初始化Cipher对象,设置为解密模式
        cipher.init(Cipher.DECRYPT_MODE, deskey);
        // 执行解密操作
        byte[] buff = cipher.doFinal(Hex.decodeHex(data.toCharArray()));
        System.out.println(Arrays.toString(buff));
        return new String(buff);
    }
    /** 
     * 生成密钥 
     * @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(Base64.decodeBase64(seed));  
       } else {  
           secureRandom = new SecureRandom();  
       }  
       KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM);  
       kg.init(secureRandom);  
       SecretKey secretKey = kg.generateKey();  
       return Base64.encodeBase64String(secretKey.getEncoded()); 
   }
    public static void main(String[] args) throws Exception {
        String key = initKey();
        System.out.println(key+"size:"+Base64.decodeBase64(key).length);
        
        String source = "Somnus";
        System.out.println("原文: " + source);
        
        String encryptData = encrypt(source, key);
        System.out.println("加密后: " + encryptData);
        
        String decryptData = decrypt(encryptData, key);
        System.out.println("解密后: " + decryptData);
    }
}

得到的输出内容如下: 

5uMCAYNX9OY=size:8
原文: Somnus
[40, 72, 46, 74, 49, 99, 10, 119]
加密后: 28482e4a31630a77
[83, 111, 109, 110, 117, 115]
解密后: Somnus

    由控制台得到的输出,我们能够比对加密、解密后结果一致。这是一种简单的加密解密方式,只有一个密钥。 
    其实DES有很多同胞兄弟,如DESede(TripleDES)、AES、Blowfish、RC2、RC4(ARCFOUR)。这里就不过多阐述了,大同小异,只要换掉ALGORITHM换成对应的值,同时做一个代码替换SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);就可以了,此外就是密钥长度不同了。 

Java代码  技术分享
  1. /** 
  2.  * DES          key size must be equal to 56 
  3.  * DESede(TripleDES) key size must be equal to 112 or 168 
  4.  * AES          key size must be equal to 128, 192 or 256,but 192 and 256 bits may not be available 
  5.  * Blowfish     key size must be multiple of 8, and can only range from 32 to 448 (inclusive) 
  6.  * RC2          key size must be between 40 and 1024 bits 
  7.  * RC4(ARCFOUR) key size must be between 40 and 1024 bits 
  8.  **/  

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。