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 }

鹽值一直在變,當然密文就跟着變啦...不錯的東東,分享給大家啦...

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM