• PBE_Passwordbased 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 }

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

  • 相关阅读:
    倍数求和
    最大(小)值
    数组扁平化:(多维数组 -> 一维数组)
    任意数求和
    找到重复最多项
    Linux 标准 I/O 库
    Linux文件操作函数
    Linux文件的IO操作 一
    Linux文件系统概述二
    Linux文件系统概述
  • 原文地址:https://www.cnblogs.com/hongten/p/hongten_pbe.html
Copyright © 2020-2023  润新知