我目前有一个代码,为我的网站哈希与盐类,所以密码是不可逆的.
目前,它是100%为我的网站工作,它是用ASP.NET(C#)编码的。
这是我的密码
public string SaltedHash(string password)
{
Salt = RandomString;
Hash = ComputeHash(Salt, password);
return Hash;
}
static string ComputeHash(string salt, string password)
{
var saltBytes = Convert.FromBase64String(salt);
using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, saltBytes, 1000))
{
return Convert.ToBase64String(rfc2898DeriveBytes.GetBytes(256));
}
}当我登录时,我使用它的方式是从数据库中的帐户中获取存储的盐,并将该盐用于当前的"ComputeHash“。
当我得到一个计算出来的散列后,我只检查它是否与数据库中的哈希匹配.
例:密码= SaltedHash(PasswordTxt);
然后,我将它与使用SQL查询的当前散列进行比较,它可以工作100%。
FYI -所有的盐都是随机生成并存储在数据库中的
现在..。我正在制作一个android应用程序,它使用的是完全相同的东西,但不幸的是,每当我试图让它工作时,它就给了我一个不同的哈希。
这是我目前的代码
public String SaltedHash(String password)
{
Hash = new String(ComputeHash(password.toCharArray(), Salt.getBytes()));
return Hash;
}
public static byte[] ComputeHash(char[] password, byte[] salt)
{
PBEKeySpec spec = new PBEKeySpec(password, salt, 1000, 256);
Arrays.fill(password, Character.MIN_VALUE);
try
{
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
return skf.generateSecret(spec).getEncoded();
}
catch (NoSuchAlgorithmException | InvalidKeySpecException e)
{
throw new AssertionError("Error while hashing a password: " + e.getMessage(), e);
}
finally
{
spec.clearPassword();
}
}这个程序被设计成完全相同的工作方式,但是不幸的是,由于某种原因,我总是得到不同的散列,有人能帮我指出我的java代码的问题吗?
这已经花了我两个星期了,我还是不能让它正常工作.我不想更改/修改C#代码.由于数据库中存在大量当前哈希密码.
更新
我忘了说我的盐号是"70“
这是我在C#中生成随机盐的代码
void GenerateRandomSalt()
{
//Create and populate random byte array
byte[] randomArray = new byte[70];
//Create random salt and convert to string
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(randomArray);
RandomString = Convert.ToBase64String(randomArray);
}更新
我对JAVA代码做了一些调整,现在哈希看起来与C#生成的哈希更相似,只是不太准确,我要做的更多一些。
public String SaltedHash(String password)
{
Hash = new String(Base64.encodeToString(ComputeHash(password.toCharArray(), Salt.getBytes()), Base64.DEFAULT));
return Hash;
}发布于 2017-04-22 17:55:25
rfc2898DeriveBytes.GetBytes(256)意味着您将得到256个字节。new PBEKeySpec(password, salt, 1000, 256)意味着您将得到256个位。
将其更改为rfc2898DeriveBytes.GetBytes(32),因为256个字节太大,安全性改进实际上可能是负面的。在计算的哈希和存储的哈希之间实现一个常数时间比较函数将更为重要。如果你不这么做,那就有可能强行输入密码。
另一个问题是您正在从Base64 in C# (var saltBytes = Convert.FromBase64String(salt);)中解码salt,但是您使用默认字符编码(可能是UTF-8)来用Java (Salt.getBytes())解码salt。您必须使用相同的解码,这意味着您必须用Java从Base64解码。
https://stackoverflow.com/questions/43561598
复制相似问题