• Java密码库Password4j


    Password4j 是一个 Java用户友好的密码库,用于使用不同的密钥派生函数(KDF) 和密码哈希函数(CHF) 对密码进行散列和检查。

    可以通过编程方式或通过类路径中的属性文件配置算法,请参阅配置部分

    配置主要取决于您的环境。Password4j 提供了一个工具,可以根据系统性能和所需的最大计算时间创建一组最佳参数,请参阅性能部分

     

     

     

    该库完全支持Argon2bcryptscryptPBKDF2 ,并且可以生成和 处理加密椒盐

    文档

     

    完整的文档可以在这里找到。为了快速开始,您可以按照README.md.

    可以在此处找到 javadoc 。

    安装

    Password4j 在任何供应商的Java 8 或更高版本上运行。Android API 21+也支持它。

    工件被部署到Maven Central

    马文

    将最新版本的依赖项添加到您的pom.xml

    
        com.password4j
        password4j
        1.6.0
    

    摇篮

    添加到您的build.gradle模块依赖项:

    repositories {
        mavenCentral()
    }
    
    dependencies {
        implementation 'com.password4j:password4j:1.6.0'
    }

    斯卡拉 SBT

    build.sbt添加到最新版本的托管依赖项:

    libraryDependencies += "com.password4j" % "password4j" % "1.6.0"

    用法

    Password4j 提供了三个主要功能:密码散列、散列检查和散列更新。

    哈希密码

    这是使用 CHF 散列密码的最简单方法(在这种情况下为 bcrypt)

    Hash hash = Password.hash(password).withBcrypt();

    盐和胡椒可以选择添加到构建器中(在这种情况下为 PBKDF2):

    // PBKDF2 with salt 12 bytes long (randomly generated).
    Hash hash = Password.hash(password).addRandomSalt(12).withPBKDF2();
    
    // PBKDF2 with a chosen salt.
    Hash hash = Password.hash(password).addSalt(salt).withPBKDF2();
    
    // PBKDF2 with chosen salt and pepper.
    Hash hash = Password.hash(password).addSalt(salt).addPepper(pepper).withPBKDF2();
    
    // Custom PBKDF2 (PBKDF2 with HMAC-SHA512, 64000 iterations and 512bit length).
    Hash hash = Password.hash(password).with(PBKDF2Function.getInstance(Hmac.SHA512, 64000, 512));

    其他 CHF 可以采用相同的结构,而不仅仅是 PBKDF2。

    验证哈希

    您可以同样轻松地验证哈希:

    boolean verified = Password.check(password, hash).withBcrypt();

    盐和胡椒可以选择添加到构建器中(在这种情况下为 PBKDF2):

    // Verify with PBKDF2.
    boolean verification = Password.check(password, hash).withPBKDF2();
    
    // Verify with PBKDF2 and manually provided salt.
    boolean verification = Password.check(password, hash).addSalt(salt).withPBKDF2();
    
    // Verify with PBKDF2 and manually provided salt and pepper.
    boolean verification = Password.check(password, hash).addSalt(salt).addPepper(pepper).withPBKDF2();

    其他算法可以采用相同的结构,而不仅仅是 PBKDF2。考虑到 Argon2、bcrypt 和 scrypt 将盐存储在哈希中,因此addSalt()不需要该方法。

    // Verify with Argon2, reads the salt from the given hash.
    boolean verification = Password.check(password, hash).withArgon2();

    一些算法将用于计算该哈希的参数编码到哈希中,特别是 bcrypt、scrypt 和 Argon2。检查散列时,您可以使用散列中的参数而不是 Password4j 配置的默认值。

    // Verify with Argon2, reads the salt and parameters from the given hash.
    boolean verification = Password.check(password, hash)..with(Argon2Function.getInstanceFromHash(hash)));

    更新哈希

    当配置被认为不再安全时,您可以使用更现代的算法刷新哈希,如下所示:

    // Reads the latest configurations in your psw4j.properties
    HashUpdate update = Password.check(password, hash).update().withBcrypt();
    
    if(update.isVerified())
    {
        Hash newHash = update.getHash();
    }

    或者,如果您想从 CHF 切换到另一个:

    PBKDF2Function pbkdf2 = AlgorithmFinder.getPBKDF2Instance();
    HashUpdate update = Password.check(password, hash).update().withScrypt(pbkdf2);
    
    if(update.isVerified())
    {
        Hash newHash = update.getHash();
    }

    不安全的算法

    许多系统可能仍然使用不安全的算法来存储密码,例如MD5SHA-256。您可以使用 Password4j 轻松迁移到更强大的算法

    MessageDigestFunction md = MessageDigestFunction.getInstance("SHA-256");
    HashUpdate update = Password.check(password, hash).update().withScrypt(md);
    
    if(update.isVerified())
    {
        Hash newHash = update.getHash();
    }

    支持的算法列表

    密钥派生函数自从笔记
    PBKDF21.0.0取决于您的 JVM 提供的安全服务
    bcrypt1.0.0
    脚本1.0.0
    氩气21.5.0
    加密哈希函数自从笔记
    医学博士家庭1.4.0
    SHA1 系列1.4.0
    SHA2 系列1.4.0
    SHA3​​家族1.4.0取决于您的 JVM 提供的安全提供程序

    字符串的安全性

    Strings 是不可变的对象,一旦存储在内存中,在垃圾收集之前您无法擦除它们。始终建议使用char[]而不是String存储密码(如果可能 - 如果我们谈论的是 Web 应用程序,大多数 Web 容器会将密码HttpServletRequest以明文形式传递给对象String)。

    能够转储内存的攻击者可以在您将密码用作 Password4j 的输入之前读取密码;即使在使用后读取,也不能保证何时发生垃圾回收:这意味着密码可能会无限期地存储在内存中,并且其值无法擦除。

    出于这个原因,Password4j 提供了一个SecureString类来缓解这个问题。提供 char[]的内容被包裹起来,并且在此过程中SecureString永远不会转换为。String

    char[]您可以使用方法擦除底层证券clear()

    SecureString secure = new SecureString(new char[]{...});
    
    Password.hash(secure).withBcrypt();
    Password.check(secure, hash).withBcrypt();
    
    secure.clear();
    // At this point the underlying char[] = {\0, \0, \0, ...}

    除此之外,您可能还需要清洁原始char[]. 使用以下代码,即使源代码也归零:

    char[] password = {...}
    SecureString secure = new SecureString(password, true);
    
    // At this point password = {\0, \0, \0, ...}

    辣椒也可以表达SecureString

    使用SecureStringchar[]不完全保护您免受攻击:垃圾收集器不断将对象从from 空间复制到to 空间,擦除原件char[]不会擦除其副本;此外,永远不能保证clear()在垃圾收集之前应用。由于这些原因,使用SecureStringchar[]只是减少了攻击者的机会窗口。

    JCA

    Password4j 与 JCA 兼容。有关更多详细信息,请参阅此项目

    配置

    Password4j 提供了一种配置库的可移植方式。

    使用放在类路径中的属性文件psw4j.properties,您可以定义所有支持的 CHF 的参数,或者只定义您需要的 CHF。或者,您可以使用系统属性指定自定义路径-Dpsw4j.configuration

    java -Dpsw4j.configuration=/my/path/to/some.properties ...

    这是一个基本配置(请不要在生产中使用它,而是在您的目标环境中启动基准会话,请参阅性能部分

    ### Argon2
    hash.argon2.memory=4096
    hash.argon2.iterations=20
    hash.argon2.length=128
    hash.argon2.parallelism=4
    hash.argon2.type=id
    
    
    ### bcrypt
    hash.bcrypt.minor=b
    # logarithmic cost (cost = 2^12)
    hash.bcrypt.rounds=12
    
    
    ### scrypt
    # N
    hash.scrypt.workfactor=16384
    # r
    hash.scrypt.resources=16
    # p
    hash.scrypt.parallelization=1
    # length
    hash.scrypt.derivedKeyLength=64
    
    ### PBKDF2
    # with HMAC-SHA256
    hash.pbkdf2.algorithm=SHA256
    # 64000 iterations
    hash.pbkdf2.iterations=64000
    # derived key of 256bit 
    hash.pbkdf2.length=256
    
    
    ### Legacy MessageDisgest
    # algorithm
    hash.md.algorithm=SHA-512
    # append/prepend salt
    hash.md.salt.option=append

    此外,您可以在此处定义您的共享辣椒

    global.pepper=AlicePepper

    并像这样使用它

    // Hash
    Password.hash("password").addPepper().withScrypt();
    
    // Verify
    Password.check("password", "hash").addPepper().withScrypt();

    SecureRandom可以被实例化并用于SecureRandom.getInstanceStrong()生成盐和胡椒。

    global.random.strong=true

    但请确保您的 JVM 支持它并且它指向一个非阻塞的熵源,否则您可能会遇到巨大的性能下降,请参阅SecureRandom

    表现

    此工具必须在目标系统中使用,因为不同环境下的性能可能会有所不同。

    Password4j 附带一个工具,可帮助开发人员为特定的 CHF 选择正确的参数。

    该类SystemChecker可用于找到这些最佳值。

    在 wiki 中,您可以找到如何根据您的响应要求配置PBKDF2bcryptscryptArgon2 。

    贡献

     

    请阅读CONTRIBUTING.md了解我们的行为准则的详细信息,以及向我们提交拉取请求的流程。

    版本控制

    我们使用SemVer进行版本控制。

    有关可用版本,请参阅此存储库上的版本。

    作者

    • David Bertoldi -主要维护者firaja

    另请参阅参与此项目的贡献者列表。

    执照

    该项目在 Apache License 2.0 License 下获得许可 - 请参阅LICENSE文件了解详细信息

    变更日志

    有关每个版本的更详细说明,请参阅CHANGELOG.md文件。

  • 相关阅读:
    Java基于PHP+MySQL客户信息管理系统的设计与实现
    【含2023java面试题】分布式锁方案设计:防止取消订单误支付Bug
    初识Springboot
    第三次裸心会
    Android AIDL Callback的使用(配源码)
    硝酸根离子深度去除树脂
    Uniapp导出的iOS应用上架详解
    InputMan12.0J、VB.net、imTime
    TET phosphoramidite, 6-isomer,TET磷酰胺,6-异构体,CAS number: 877049-90-6
    《持续交付:发布可靠软件的系统方法》- 读书笔记(十二)
  • 原文地址:https://blog.csdn.net/allway2/article/details/126733248