java程序猿的成长记录之(三)分享一种防猜的加密算法

在日常开发中,数据库用户表密码的存放一般不会放置明文密码.就算存的是加密后的,相同密码加密后获得的字符串也是相同的.今天博主学习了一种加密算法,每次生成的密文不同
废话少说,开始coding....

生成随机的Byte[]作为salt

//  numBytes为想要生成"盐"的长度
private static byte[] generateSalt(int numBytes) {
    byte[] bytes = new byte[numBytes];
    new SecureRandom().nextBytes(bytes);
    return bytes;
}

HTML 解码

//htmlEscaped 为想要加密的字符串
private static String unescapeHtml(String htmlEscaped) {
    return StringEscapeUtils.unescapeHtml4(htmlEscaped);
}

Hex编码

private static String encodeHex(byte[] input) {
    return new String(Hex.encodeHex(input));
}

Hex解码

private static byte[] decodeHex(String input) {
    byte[] bytes = null;
        try {
            bytes = Hex.decodeHex(input.toCharArray());
        } catch (DecoderException e) {
            e.printStackTrace();
        }
    return bytes;
}

对字符串进行散列(精华部分)

    /**
     * iterations sha-1的次数
     * salt 参与算法的盐
     * input 参与算法的字符串.getBytes()
     */
private static byte[] digest(byte[] input, byte[] salt, int iterations) {
    MessageDigest digest = null;
    try {
        //这里也可以MD5
        digest = MessageDigest.getInstance("SHA-1");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    if (salt != null) {
        digest.update(salt);
    }
    byte[] result = digest.digest(input);
    for (int i = 1; i < iterations; i++) {
        digest.reset();
        result = digest.digest(result);
    }
    return result;
}

准备工作完毕,开始进行安全字符串的生成

public static String createSign(String sign) {
    //将目标字符串进行处理
    String plain = unescapeHtml(sign);
    //生成参与算法的盐
    byte[] salt = generateSalt(8);
    //经过1024次sha-1.
    byte[] hashStr = digest(plain.getBytes(),salt,1024);
    //返回密文
    return encodeHex(salt) + encodeHex(hashStr);
}

由于是单向加密,对生成密文无法解密,所以我们判定方法为将目标字符串再次进行加密看与之前加密过的hash相同与否

    /**
     * sign 目标字符串
     * hashSign 已存在的密文
     */
public static boolean validateSign(String sign, String hashSign) {
    String plain = unescapeHtml(sign);
    //得到上次上次参与算法的盐
    byte[] salt = decodeHex(hashSign.substring(0, 16));
    byte[] hashStr = digest(plain.getBytes(), salt,1028);
    return hashSign.equals(encodeHex(salt)+ encodeHex(hashStr));
}

我们来验证下:

public static void main(String[] args) {
    System.out.println("wisty字符串第一次加密结果:"+createSign("wisty"));
    System.out.println("wisty字符串第二次加密结果:"+createSign("wisty"));
    System.out.println("wisty字符串第三次加密结果:"+createSign("wisty"));
    System.out.println("wisty字符串第四次加密结果:"+createSign("wisty"));
}
------------------结果如下--------------
wisty字符串第一次加密结果:8d4b1d479556a3fea133e7ce663d778d5ad47606ea4d02192e174f46
wisty字符串第二次加密结果:8ed8b6bf9860139679a7161c8afd4ebe4dbef6f951231adbd7757e1c
wisty字符串第三次加密结果:75a1146425ed57067d22332b11f628ee822e725f625b778231c14162
wisty字符串第四次加密结果:21f513cf5e8f793ee3af9b1f210b08803c5bab614fbd543791e6ba29
public static void main(String[] args) {
    System.out.println("明密文第一次比较结果:"+validateSign("wisty","8d4b1d479556a3fea133e7ce663d778d5ad47606ea4d02192e174f46"));
    System.out.println("明密文第二次比较结果:"+validateSign("wisty","8ed8b6bf9860139679a7161c8afd4ebe4dbef6f951231adbd7757e1c"));
    System.out.println("明密文第三次比较结果:"+validateSign("wisty","75a1146425ed57067d22332b11f628ee822e725f625b778231c14162"));
    System.out.println("明密文第四次比较结果:"+validateSign("wisty","21f513cf5e8f793ee3af9b1f210b08803c5bab614fbd543791e6ba29"));
    ------------------结果如下--------------
    明密文第一次比较结果:true
    明密文第二次比较结果:true
    明密文第三次比较结果:true
    明密文第四次比较结果:true

从上面我们可以看到每次生成的密文都不同,通过比较密文指向同一个明文………..
欢迎大家交流学习

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值