0

In yii2 using generatePasswordHash and validatePassword to verify password like this. After encrypted it store in DB with password_hash

$2y$13$1hVeVwvuKQUE.kJfaQLje.b8iLlTauTOksddD5Gqn6UC416NsnAR2

auth_key oEx6MM0pGs6jHvApr2anxJEINpTpqGUO

Now how to using java to verify the password? And what is the auth_key means, as verify don't need to input the auth_key.

ScaisEdge
  • 131,976
  • 10
  • 91
  • 107
forqzy
  • 389
  • 2
  • 11
  • https://stackoverflow.com/questions/18142745/how-do-i-generate-a-salt-in-java-for-salted-hash – forqzy Feb 15 '21 at 23:34

2 Answers2

1

All you need is create your custom Class in Java taking and converting from PHP class \yii\base\Security (source is here). Regarding auth key this question already asked here in SO

sambua
  • 2,274
  • 3
  • 22
  • 20
0

Finally solved with the following, the tricky part is replace the header.

public class CheckPassword {

public static boolean checkPassword(String passwordText, String DbHash) {
    boolean password_verified = false;
    if (null != DbHash) {
        if (DbHash.startsWith("$2y$")) {
            DbHash = "$2a$" + DbHash.substring(4);
        }
    }

    if (null == DbHash || !DbHash.startsWith("$2a$")) {
        throw new java.lang.IllegalArgumentException("Invalid hash provided for comparison");
    }
    password_verified = BCrypt.checkpw(passwordText, DbHash);
    return (password_verified);
}

public static void main(String[] args) {
    CheckPassword.checkPassword("xxxxx", "$2y$13$5mqgv2wZve89Bz.g1MUcg.7xNich7/nxxxxxxxxxx");

    try {
        String salt = getSalt();
        System.out.println("salt:" + salt);//获取salt
        String miwen = getPBKDF2("111", salt); //明文密码加密
        System.out.println("miwen:" + miwen);
        System.out.println(salt + miwen);
        System.out.println(verify("111", salt + miwen));//解密


    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1";

//盐的长度
public static final int SALT_SIZE = 16;

//生成密文的长度
public static final int HASH_SIZE = 16;

// 迭代次数
public static final int PBKDF2_ITERATIONS = 1000;

/**
 * 对输入的密码进行验证
 * password 密码明文
 * dataPassWord 密码加密
 */
public static boolean verify(String password, String dataPassWord)
        throws NoSuchAlgorithmException, InvalidKeySpecException {
    // 用相同的盐值对用户输入的密码进行加密
    String result = getPBKDF2(password, dataPassWord.substring(0, 16));
    // 把加密后的密文和原密文进行比较,相同则验证成功,否则失败
    return result.equals(dataPassWord.substring(16, dataPassWord.length()));
}

/**
 * 根据password和salt生成密文
 */
public static String getPBKDF2(String password, String salt) throws NoSuchAlgorithmException,
        InvalidKeySpecException {
    //将16进制字符串形式的salt转换成byte数组
    byte[] bytes = DatatypeConverter.parseHexBinary(salt);
    KeySpec spec = new PBEKeySpec(password.toCharArray(), bytes, PBKDF2_ITERATIONS, HASH_SIZE * 4);
    SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);
    byte[] hash = secretKeyFactory.generateSecret(spec).getEncoded();
    //将byte数组转换为16进制的字符串
    return DatatypeConverter.printHexBinary(hash);
}


/**
 * 生成随机盐值
 */
public static String getSalt() throws NoSuchAlgorithmException {
    SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
    byte[] bytes = new byte[SALT_SIZE / 2];
    random.nextBytes(bytes);
    //将byte数组转换为16进制的字符串
    String salt = DatatypeConverter.printHexBinary(bytes);
    return salt;
}

}

forqzy
  • 389
  • 2
  • 11