再谈谈Java加密技术(三)

七月 25, 2008 | 标签 加密  base64  md5  mac  sha  单向加密   | 浏览
评论 0
除了DES,我们还知道有DESede(TripleDES,就是3DES)、AES、Blowfish、RC2、RC4(ARCFOUR)等多种对称加密方式,其实现方式大同小异,这里介绍对称加密的另一个算法——PBE

PBE
PBE——Password-based encryption(基于密码加密)。其特点在于口令由用户自己掌管,不借助任何物理媒体;采用随机数(这里我们叫做盐)杂凑多重加密等方法保证数据的安全性。是一种简便的加密方式。


通过java代码实现如下:

import java.security.Key;   
import java.util.Random;   
  
import javax.crypto.Cipher;   
import javax.crypto.SecretKey;   
import javax.crypto.SecretKeyFactory;   
import javax.crypto.spec.PBEKeySpec;   
import javax.crypto.spec.PBEParameterSpec;   
  
/** *//**  
 * PBE安全编码组件 http://www.bt285.cn   http://www.5a520.cn 
 *   
 * @author 梁栋  
 * @version 1.0  
 * @since 1.0  
 */  
public abstract class PBECoder extends Coder {   
    /** *//**  
     * 支持以下任意一种算法  
     *   
     * <pre>  
     * PBEWithMD5AndDES   
     * PBEWithMD5AndTripleDES   
     * PBEWithSHA1AndDESede  
     * PBEWithSHA1AndRC2_40  
     * </pre>  
     */  
    public static final String ALGORITHM = "PBEWITHMD5andDES";   
  
    /** *//**  
     * 盐初始化  
     *   
     * @return  
     * @throws Exception  
     */  
    public static byte[] initSalt() throws Exception {   
        byte[] salt = new byte[8];   
        Random random = new Random();   
        random.nextBytes(salt);   
        return salt;   
    }   
  
    /** *//**  
     * 转换密钥<br>  
     *   
     * @param password  
     * @return  
     * @throws Exception  
     */  
    private static Key toKey(String password) throws Exception {   
        PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());   
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);   
        SecretKey secretKey = keyFactory.generateSecret(keySpec);   
  
        return secretKey;   
    }   
  
    /** *//**  
     * 加密  
     *   
     * @param data  
     *            数据  
     * @param password  
     *            密码  
     * @param salt  
     *            盐  
     * @return  
     * @throws Exception  
     */  
    public static byte[] encrypt(byte[] data, String password, byte[] salt)   
            throws Exception {   
  
        Key key = toKey(password);   
  
        PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);   
        Cipher cipher = Cipher.getInstance(ALGORITHM);   
        cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);   
  
        return cipher.doFinal(data);   
  
    }   
  
    /** *//**  
     * 解密  
     *   
     * @param data  
     *            数据  
     * @param password  
     *            密码  
     * @param salt  
     *            盐  
     * @return  
     * @throws Exception  
     */  
    public static byte[] decrypt(byte[] data, String password, byte[] salt)   
            throws Exception {   
  
        Key key = toKey(password);   
  
        PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);   
        Cipher cipher = Cipher.getInstance(ALGORITHM);   
        cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);   
  
        return cipher.doFinal(data);   
  
    }   
}  

再给出一个测试类:

import static org.junit.Assert.*;   
  
import org.junit.Test;   
  
/** *//**  
 *   
 * @author 梁栋  http://www.5a520.cn http://www.feng123.com
 * @version 1.0  
 * @since 1.0  
 */  
public class PBECoderTest {   
  
    @Test  
    public void test() throws Exception {   
        String inputStr = "abc";   
        System.err.println("原文: " + inputStr);   
        byte[] input = inputStr.getBytes();   
  
        String pwd = "efg";   
        System.err.println("密码: " + pwd);   
  
        byte[] salt = PBECoder.initSalt();   
  
        byte[] data = PBECoder.encrypt(input, pwd, salt);   
  
        System.err.println("加密后: " + PBECoder.encryptBASE64(data));   
  
        byte[] output = PBECoder.decrypt(data, pwd, salt);   
        String outputStr = new String(output);   
  
        System.err.println("解密后: " + outputStr);   
        assertEquals(inputStr, outputStr);   
    }   
  
}  

控制台输出:
# 原文: abc
# 密码: efg
# 加密后: iCZ0uRtaAhE=
#
# 解密后: abc




发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。