我有一个应用程序,可能需要一个验证密码。
这个应用程序不处理任何敏感数据,因为这个“密码”是由主机选择的,并通过另一个通道(whatsapp或其他什么)告诉“客户机”。因此,当客户机想要进行身份验证时,主机会生成一个随机字符串,并将其发送给客户机。
然后,客户机用用户输入的密码加密这个随机字符串。
加密的随机字符串是发送回主机的字符串。
主机使用同一密码生成的密钥解密此加密字符串。
如果未加密字符串与原始字符串匹配,则用户已登录。
到目前为止我想到的是:
String base64;
char[] password = "password".toCharArray();
String randomString = new BigInteger(130, new SecureRandom()).toString(32);
try {
//Encrypt Client Side
SecretKey key = new SecretKeySpec(SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512").generateSecret(new PBEKeySpec(password)).getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key);
base64 = Base64.getEncoder().encodeToString(cipher.doFinal(randomString.getBytes(StandardCharsets.UTF_8)));
} catch (GeneralSecurityException e) {
throw new IllegalStateException(e);
}
try {
//Decrypt Server Side
SecretKey key = new SecretKeySpec(SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512").generateSecret(new PBEKeySpec(password)).getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key);
//Check if both strings match
System.out.println(Arrays.equals(cipher.doFinal(Base64.getDecoder().decode(base64)), randomString.getBytes(StandardCharsets.UTF_8)));
} catch (GeneralSecurityException e) {
throw new IllegalStateException(e);
}
不幸的是,此代码引发了一个异常: java.security.spec.InvalidKeySpecException: Salt not found
我应该使用不同的算法,还是通过散列密码本身来生成salt,或者使用完全不同的方法?我希望避免将生成的salt与随机字符串一起发送
1条答案
按热度按时间hjqgdpho1#
你应该给
PBEKeySpec
它需要为aes密钥生成足够的位。两边都需要同样的盐,所以你可以:现在替换你的
PBEKeySpec
与new PBEKeySpec(password, salt, 10, 128)
一切都应该正常。