PBE_Password-based encryption(基于密码加密)_项目中你也可以有

在一篇blog名叫:项目中加密存储密码的工具类---PasswordUtil类

中说道了PBE——Password-based encryption(基于密码加密)。我也做测试了一下,现在把我做的效果给大家演示一下:

运行效果:

==============================================================

代码部分:

==============================================================

/pbe/src/com/b510/passwordutil/PasswordUtil.java

  1 /**
  2  * 
  3  */
  4 package com.b510.passwordutil;
  5 
  6 import java.security.Key;
  7 import java.security.SecureRandom;
  8 
  9 import javax.crypto.Cipher;
 10 import javax.crypto.SecretKey;
 11 import javax.crypto.SecretKeyFactory;
 12 import javax.crypto.spec.PBEKeySpec;
 13 import javax.crypto.spec.PBEParameterSpec;
 14 
 15 /**
 16  * PBE——Password-based encryption(基于密码加密)。<br>
 17  * 其特点在于口令由用户自己掌管,不借助任何物理媒体;采用随机数(这里我们叫做盐)杂凑多重加密等方法保证数据的安全性。<br>
 18  * 是一种简便的加密方式。<br>
 19  * 
 20  * @author <a href="mailto:hongtenzone@foxmail.com">hongten</a><br>
 21  * @date 2013-4-3<br>
 22  * 
 23  * @see <a href="http://blog.csdn.net/hexingzhi/article/details/7424872">原文</a>
 24  */
 25 public class PasswordUtil {
 26 
 27     /**
 28      * JAVA6支持以下任意一种算法 PBEWITHMD5ANDDES PBEWITHMD5ANDTRIPLEDES<测试的时候报错>
 29      * PBEWITHSHAANDDESEDE<测试的时候报错> PBEWITHSHA1ANDRC2_40 PBKDF2WITHHMACSHA1<测试的时候报错>
 30      * */
 31 
 32     /**
 33      * 本地测试通过:<code>PBEWITHMD5ANDDES</code>,<code>PBEWITHSHA1ANDRC2_40</code>
 34      */
 35     
 36     /**
 37      * 定义使用的算法为:PBEWITHMD5andDES算法
 38      */
 39     public static final String ALGORITHM = "PBEWITHMD5ANDDES";
 40 
 41     /**
 42      * 定义迭代次数为1000次
 43      */
 44     private static final int ITERATIONCOUNT = 1000;
 45 
 46     /**
 47      * 获取加密算法中使用的盐值,解密中使用的盐值必须与加密中使用的相同才能完成操作. 盐长度必须为8字节
 48      * 
 49      * @return byte[] 盐值
 50      * */
 51     public static byte[] getSalt() throws Exception {
 52         // 实例化安全随机数
 53         SecureRandom random = new SecureRandom();
 54         // 产出盐
 55         return random.generateSeed(8);
 56     }
 57 
 58     /**
 59      * 根据PBE密码生成一把密钥
 60      * 
 61      * @param password
 62      *            生成密钥时所使用的密码
 63      * @return Key PBE算法密钥
 64      * */
 65     private static Key getPBEKey(String password) throws Exception {
 66         // 实例化使用的算法
 67         SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
 68         // 设置PBE密钥参数
 69         PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
 70         // 生成密钥
 71         SecretKey secretKey = keyFactory.generateSecret(keySpec);
 72 
 73         return secretKey;
 74     }
 75 
 76     /**
 77      * 加密明文字符串
 78      * 
 79      * @param plaintext
 80      *            待加密的明文字符串
 81      * @param password
 82      *            生成密钥时所使用的密码
 83      * @param salt
 84      *            盐值
 85      * @return 加密后的密文字符串
 86      * @throws Exception
 87      */
 88     public static String encrypt(String plaintext, String password, byte[] salt)
 89             throws Exception {
 90 
 91         Key key = getPBEKey(password);
 92 
 93         PBEParameterSpec parameterSpec = new PBEParameterSpec(salt,
 94                 ITERATIONCOUNT);
 95 
 96         Cipher cipher = Cipher.getInstance(ALGORITHM);
 97 
 98         cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
 99 
100         byte encipheredData[] = cipher.doFinal(plaintext.getBytes());
101 
102         return bytesToHexString(encipheredData);
103     }
104 
105     /**
106      * 解密密文字符串
107      * 
108      * @param ciphertext
109      *            待解密的密文字符串
110      * @param password
111      *            生成密钥时所使用的密码(如需解密,该参数需要与加密时使用的一致)
112      * @param salt
113      *            盐值(如需解密,该参数需要与加密时使用的一致)
114      * @return 解密后的明文字符串
115      * @throws Exception
116      */
117     public static String decrypt(String ciphertext, String password, byte[] salt)
118             throws Exception {
119 
120         Key key = getPBEKey(password);
121 
122         PBEParameterSpec parameterSpec = new PBEParameterSpec(salt,
123                 ITERATIONCOUNT);
124 
125         Cipher cipher = Cipher.getInstance(ALGORITHM);
126 
127         cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);
128 
129         byte[] passDec = cipher.doFinal(hexStringToBytes(ciphertext));
130 
131         return new String(passDec);
132     }
133 
134     /**
135      * 将字节数组转换为十六进制字符串
136      * 
137      * @param src
138      *            字节数组
139      * @return
140      */
141     public static String bytesToHexString(byte[] src) {
142         StringBuilder stringBuilder = new StringBuilder("");
143         if (src == null || src.length <= 0) {
144             return null;
145         }
146         for (int i = 0; i < src.length; i++) {
147             int v = src[i] & 0xFF;
148             String hv = Integer.toHexString(v);
149             if (hv.length() < 2) {
150                 stringBuilder.append(0);
151             }
152             stringBuilder.append(hv);
153         }
154         return stringBuilder.toString();
155     }
156 
157     /**
158      * 将十六进制字符串转换为字节数组
159      * 
160      * @param hexString
161      *            十六进制字符串
162      * @return
163      */
164     public static byte[] hexStringToBytes(String hexString) {
165         if (hexString == null || hexString.equals("")) {
166             return null;
167         }
168         hexString = hexString.toUpperCase();
169         int length = hexString.length() / 2;
170         char[] hexChars = hexString.toCharArray();
171         byte[] d = new byte[length];
172         for (int i = 0; i < length; i++) {
173             int pos = i * 2;
174             d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
175         }
176         return d;
177     }
178 
179     private static byte charToByte(char c) {
180         return (byte) "0123456789ABCDEF".indexOf(c);
181     }
182     
183     
184     public static void main(String[] args) {
185         String str = "hongtenzone@foxmail.com";
186         String password = "hongten123";
187 
188         System.out.println("明文:" + str);
189         System.out.println("密码:" + password);
190 
191         try {
192             byte[] salt = PasswordUtil.getSalt();
193             System.out.println("盐值:"+salt.toString());
194             String ciphertext = PasswordUtil.encrypt(str, password, salt);
195             System.out.println("密文:" + ciphertext);
196             String plaintext = PasswordUtil.decrypt(ciphertext, password, salt);
197             System.out.println("明文:" + plaintext);
198         } catch (Exception e) {
199             e.printStackTrace();
200         }
201     }
202 }

盐值一直在变,当然密文就跟着变啦...不错的东东,分享给大家啦...

 

 

posted @ 2013-04-03 16:43  Hongten  阅读(3977)  评论(0编辑  收藏  举报
Fork me on GitHub