用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字
云代码 - java代码库

生成一个固定位数的随机字符串,并加密,和用户密码加密后的密文组合

2017-09-07 作者: 低调的小飞举报

[java]代码库

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
 
/**
 * 生成一个固定位数的随机字符串,并加密,和用户密码加密后的密文组合
 *
 */
public class PasswordUtil {
 
    // 16进制需要的字符串数据
    private static final String HEX_NUMS_STR = "0123456789ABCDEF";
 
    // 随机字符串字节数长度
    private static final Integer BYTE_LENGTH = 16;
 
    /**
     * 将16进制字符串转换成字节数组
     *
     * @param hex
     * @return
     */
    public static byte[] hexStringToByte(String hex) {
        int len = (hex.length() / 2);
        byte[] result = new byte[len];
        char[] hexChars = hex.toCharArray();
        for (int i = 0; i < len; i++) {
            int pos = i * 2;
            result[i] = (byte) (HEX_NUMS_STR.indexOf(hexChars[pos]) << 4 | HEX_NUMS_STR
                    .indexOf(hexChars[pos + 1]));
        }
        return result;
    }
 
    /**
     * 将指定byte数组转换成16进制字符串
     *
     * @param b
     * @return
     */
    public static String byteToHexString(byte[] b) {
        StringBuffer hexString = new StringBuffer();
        for (int i = 0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            hexString.append(hex.toUpperCase());
        }
        return hexString.toString();
    }
 
    /**
     * 验证口令是否合法
     *
     * @param inputStr
     * @param strWithRandom
     * @return
     * @throws NoSuchAlgorithmException
     * @throws UnsupportedEncodingException
     */
    public static boolean validPassword(String inputStr, String strWithRandom) {
        boolean flag = false;
        try {
            // 将16进制字符串格式口令转换成字节数组
            byte[] pwdInDb = hexStringToByte(strWithRandom);
            // 声明一个随机数组变量
            byte[] randomByte = new byte[BYTE_LENGTH];
            // 将随机数组从数据库中保存的口令字节数组中提取出来,按其长度
            System.arraycopy(pwdInDb, 0, randomByte, 0, BYTE_LENGTH);
            // 创建消息摘要对象
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 将随机数组据传入消息摘要对象
            md.update(randomByte);
            // 将口令的数据传给消息摘要对象
            md.update(inputStr.getBytes("UTF-8"));
            // 生成输入口令的消息摘要
            byte[] digest = md.digest();
            // 声明一个保存数据库中口令消息摘要的变量
            byte[] digestInDb = new byte[pwdInDb.length - BYTE_LENGTH];
            // 取得数据库中口令的消息摘要
            System.arraycopy(pwdInDb, BYTE_LENGTH, digestInDb, 0,
                    digestInDb.length);
            // 比较根据输入口令生成的消息摘要和数据库中消息摘要是否相同
            if (Arrays.equals(digest, digestInDb)) {
                // 口令正确返回口令匹配消息
                flag = true;
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return flag;
    }
 
    /**
     * 获得加密后的16进制形式口令
     *
     * @param password
     * @return
     * @throws NoSuchAlgorithmException
     * @throws UnsupportedEncodingException
     */
    public static String MD5(String password) {
        // 声明加密后的口令数组变量
        byte[] pwd = null;
        // 随机数生成器
        SecureRandom random = new SecureRandom();
        // 声明随机数组变量
        byte[] randomByte = new byte[BYTE_LENGTH];
        try {
            // 将随机数放入随机数组变量中
            //用随机数填充指定字节数组的元素。
            random.nextBytes(randomByte);
 
            // 声明消息摘要对象
            MessageDigest md = null;
            // 创建消息摘要
            md = MessageDigest.getInstance("MD5");
            // 将盐数据传入消息摘要对象
            md.update(randomByte);
            // 将口令的数据传给消息摘要对象
            md.update(password.getBytes("UTF-8"));
            // 获得消息摘要的字节数组
            byte[] digest = md.digest();
 
            // 因为要在口令的字节数组中存放随机数组密文,所以加上随机数组的字节长度
            pwd = new byte[digest.length + BYTE_LENGTH];
            // 将盐的字节拷贝到生成的加密口令字节数组的前相应该长度BYTE_LENGTH个字节,以便在验证口令时取出随机数组
            System.arraycopy(randomByte, 0, pwd, 0, BYTE_LENGTH);
            // 将消息摘要拷贝到加密口令字节数组从第BYTE_LENGTH个字节开始的字节
            System.arraycopy(digest, 0, pwd, BYTE_LENGTH, digest.length);
            // 将字节数组格式加密后的口令转化为16进制字符串格式的口令
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
 
        if (pwd != null) {
            return byteToHexString(pwd);
        }
 
        return null;
    }
 
}


网友评论    (发表评论)


发表评论:

评论须知:

  • 1、评论每次加2分,每天上限为30;
  • 2、请文明用语,共同创建干净的技术交流环境;
  • 3、若被发现提交非法信息,评论将会被删除,并且给予扣分处理,严重者给予封号处理;
  • 4、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

输入口令后可复制整站源码

加载中,请稍后...