Apache Codec Crypt 类用法

本文将介绍 Apache Codec 库中 Crypt 类的用法

Apache Commons Codec 库中的 org.apache.commons.codec.digest.Crypt 类是 GNU libc crypt(3) 兼容哈希方法,注意:这个类是不可变的和线程安全的。有关更多细节,请参见 crypt(String, String) 方法。该方法定义如下:

public static String crypt(String key, String salt)

以与 crypt(3) 兼容的方式加密密码。确切的算法取决于盐字符串的格式:

  • SHA-512 盐以 $6$ 开始,且盐的长度为 16 个字符

  • SHA-256 盐以 $5$ 开始,且盐的长度为 16 个字符

  • MD5 盐以 $1$ 开始,且盐的长度为 8 个字符

  • DES,传统的 unixCrypt 算法只使用 2 个字符

  • 在DES算法中只使用密码的前8个字符!

这个方法不能识别神奇的字符串“$apr1$”和“$2a$”,因为它的输出应该与 libc 实现的输出相同。

盐字符串的其余部分是从集合 [a-Za-Z0-9.] 中提取的,如果遇到“$”符号,则以最大长度切割。因此,输入一个完整的散列值作为盐是有效的,例如用以下方法验证密码:

storedPwd.equals(crypt(enteredPwd, storedPwd))

结果字符串以标记字符串 ($n$) 开头,其中 n 与输入盐类相同。然后,盐被附加,然后是“$”标志。后面跟着实际的散列值。对于DES,字符串只包含盐和实际哈希。总长度取决于所使用的算法:

  • SHA-512: 106 chars

  • SHA-256: 63 chars

  • MD5: 34 chars

  • DES: 13 chars

实例:

crypt("secret", "$1$xxxx") => "$1$xxxx$aMkevjfEIpa35Bh3G4bAc."
crypt("secret", "xx") => "xxWAum7tHdIUw"

这个方法是一个变体,它接受一个 byte[] 数组来支持不是用 UTF-8 编码的输入字符串,例如在 ISO-8859-1 中,相同的字符会产生不同的字节值。

参数:

key - 使用的明文密码

salt - 真正的盐值,没有前缀或“rounds=”。盐可能为 NULL,在这种情况下,将使用 ThreadLocalRandomy 为您生成一个盐;要获得更安全的盐,请考虑使用 SecureRandy 类来生成您自己的盐。

返回:

哈希值,即加密密码,包括盐字符串。

示例代码

下面实例将使用带有 $6$、$5$、$1$ 和 null 的盐去调用 crypt 方法,代码如下:

package com.huangx.codec.crypt;

import org.apache.commons.codec.digest.Crypt;

public class CryptDemo {

    public static void main(String[] args) {
        String key = "aaaaaa";
        // 使用 SHA-512 加密
        System.out.println(Crypt.crypt(key, "$6$mysalt"));
        // 使用 SHA-256 加密
        System.out.println(Crypt.crypt(key, "$5$mysalt"));
        // 使用 MD5 加密
        System.out.println(Crypt.crypt(key, "$1$mysalt"));
        // 如果盐为 null,默认使用 SHA-512 加密
        System.out.println(Crypt.crypt(key, null));
    }

}

运行上面代码,输出结果如下:

$6$mysalt$nloQP7cq./IX62jEhS0j43soq/UAy5b4ikVEVMen8gxdg3tI7dRgI4MgCVjddo0H3nS6xwad6FZgi7aEf6oMP0
$5$mysalt$IemuP40gJs0aWIl4..v3xcr4sAG5.VGP7t4AD95TZgC
$1$mysalt$nU3yTejn7ZUl1MWxOtB2T/
$6$a1r/F8LF$tpNOvl8apJU0PVL3/RcDOSFgTyN7y8qccgbduYVBPnA4FJnhoq.Kwtrk8UfEhujopQnTt6ApiyM2qxTRxOm2x.

上面代码演示了 crypt 方法的用法,剩下的三个 crypt 方法用法和上面 crypt 方法一致,只是参数不一样,它们的定义如下:

  • static String crypt(byte[] keyBytes)

    以 crypt(3) 兼容的方式加密密码。

  • static String crypt(byte[] keyBytes, String salt)

    以 crypt(3) 兼容的方式加密密码。

  • static String crypt(String key)

    使用最强的 crypt(3) 算法计算消息摘要。

实例:使用上面三个方法生成消息摘要,验证多次调用同一个方法得到的消息摘要是否一致。代码如下:

package com.huangx.codec.crypt;

import org.apache.commons.codec.digest.Crypt;

public class CryptDemo3 {

    public static void main(String[] args) {
        String key = "aaaaaa";
        // 多次加密不一致,因为使用 ThreadLocalRandomy 随机生成盐
        String a1 = Crypt.crypt(key.getBytes());
        String a2 = Crypt.crypt(key.getBytes());
        System.out.println(a1);
        System.out.println(a2);
        System.out.println(a1.equals(a2));

        // 多次加密不一致,因为使用 ThreadLocalRandomy 随机生成盐
        String b1 = Crypt.crypt(key);
        String b2 = Crypt.crypt(key);
        System.out.println(b1);
        System.out.println(b2);
        System.out.println(b1.equals(b2));

        // 多次加密均是一致的,因为盐是固定的
        String c1 = Crypt.crypt(key.getBytes(), "$6$mysalt");
        String c2 = Crypt.crypt(key.getBytes(), "$6$mysalt");
        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c1.equals(c2));
    }

}

运行上面程序,输出结果如下:

$6$VoCdj.WQ$BRIn9neDrXL7v4Pi4C2jLzPiBKNhDi6wE1CrzeLh83YLg.bwKpvmshGCl0/dPn0epqp0QSA/ex8bUcJeWS.PX1
$6$EFNq3oLR$8VrtJ2ubt2KRplnF.Rf3RkpU.5DlzGlmeV8iRNs6bXvEOySGCKZLLSY4oVIxLwYYqrgJHuhvVwmdHpUfR042v/
false
$6$F5FPJMkw$ypAe0eXVmNHySOSf649STp9mbY7FF7wcLOvqFtoCZCPZtTn3yvdwrOnhrvi.2whtxyR1MfqMTQjOdl8skxshX/
$6$bUY6NskF$nsF20ThHgXIs8OAxWIt6smWMJUREyL4oqZhhHnb1wyPv.JdVoUYpvwcqwm06rK1Gsnmb1KNIhy8Cp0x0UpG09.
false
$6$mysalt$nloQP7cq./IX62jEhS0j43soq/UAy5b4ikVEVMen8gxdg3tI7dRgI4MgCVjddo0H3nS6xwad6FZgi7aEf6oMP0
$6$mysalt$nloQP7cq./IX62jEhS0j43soq/UAy5b4ikVEVMen8gxdg3tI7dRgI4MgCVjddo0H3nS6xwad6FZgi7aEf6oMP0
true
业精于勤,荒于嬉。——韩愈《进学解》
0 不喜欢
说说我的看法 -
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号