我正在尝试使用一种登录方法,使客户端密码在我的服务器中保持安全和加密。
我在Angular中使用的库是https://github.com/middleout/angular-cryptography
这个想法是,遵循以下步骤:
我在module.config中设置了一个salt:
app.config(['$cryptoProvider', function($cryptoProvider){
$cryptoProvider.setCryptographyKey('thisismysalt');
}]);
我用自己加密密码:
user.pw = $crypto.encrypt(user.pw, user.pw);
如果我正在注册用户,我会自行重新加密密码(重复步骤2)并将其保存在数据库中。如果我正在记录,我只是将最后一步的结果发送到服务器。
当您使用单加密字符串对双重加密字符串进行解密后,您将再次获得单个加密字符串。因此,如果您的密码正确,您只需将结果与单加密字符串进行比较,然后验证用户。
好的,这种方法应该可以使用(我已经在Node中使用过了),使用SSL可以很好地保护用户的密码,即使在服务器中也是如此!
但我找不到任何可以做到的Java库或片段。我尝试了很多,但是很难理解,当我将它们调整到我的程序时,它们就无法工作了。我尝试了以下方法:
static String IV = "AAAAAAAAAAAAAAAA";
static String plaintext = "test text 123\0\0\0"; /*Note null padding*/
static String encryptionKey = "0123456789abcdef";
public static String decrypt(byte[] cipherText, String encryptionKey) throws Exception{
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE");
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
cipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8")));
return new String(cipher.doFinal(cipherText),"UTF-8");
}
我将它作为第一个参数传递,来自数据库的双重加密密码,以及作为第二个参数,来自前端的单加密密码:
java.security.InvalidKeyException:无效的AES密钥长度:44个字节
我做错了吗?我应该使用不同的算法吗?
答案 0 :(得分:1)
middleout / angular-cryptography使用CryptoJS 3.1.2 under the hood with the least effort possible。
所以
return $crypto.encrypt(plaintext, password);
与
相同$cryptoProvider.setCryptographyKey(password);
return $crypto.encrypt(plaintext, password);
与
相同return CryptoJS.AES.encrypt(plaintext, password).toString();
我在答案here中描述了如何用Java做同样的事情。
如果您正在使用SSL / TLS,那么额外执行此加密并没有多大好处。密码已通过互联网以加密方式发送。更糟糕的是,由于密码必须在服务器端可用,因此必须以明文形式存储密码。 那不是怎么做的。
你需要使用散列而不是强大的散列是PBKDF2,bcrypt,scrypt和Argon2。由于散列函数是单向函数,因此您无法解密"解密"哈希。为了验证您的用户,您可以再次通过散列函数运行密码,以便与存储在数据库中的散列进行比较。由于您已经在使用SSL / TLS,因此密码在传输过程中已经得到保护。查看更多:How to securely hash passwords?