验证C#应用程序在php中加密的密码
在我的网站上有一个页面,客户可以在其中存储密码,以便在他们购买的应用程序中使用(为了方便起见,通常为所有应用程序存储一个密码)。密码是使用PHP代码用bcrypt散列的:验证C#应用程序在php中加密的密码,c#,php,wpf,encryption,bcrypt,C#,Php,Wpf,Encryption,Bcrypt,在我的网站上有一个页面,客户可以在其中存储密码,以便在他们购买的应用程序中使用(为了方便起见,通常为所有应用程序存储一个密码)。密码是使用PHP代码用bcrypt散列的: if ( $app_pass != '' ){ $mysalt= mcrypt_create_iv(22, MCRYPT_DEV_URANDOM); $options = [ 'cost' => 10, 'salt' => $mysalt,]; $app_pass = password_hash( $a
if ( $app_pass != '' ){
$mysalt= mcrypt_create_iv(22, MCRYPT_DEV_URANDOM);
$options = [ 'cost' => 10, 'salt' => $mysalt,];
$app_pass = password_hash( $app_pass, PASSWORD_BCRYPT, $options );
}
- 如果语句为纯文本,则在
中的
$app\u pass
- 之后成为bcrypted散列
- 然后该散列存储在MySQL数据库中
BCryptHelper
class验证输入的密码:
BCryptHelper.CheckPassword(passwordbox.Password, hashFromDb)
但它返回错误代码:
DevOne.Security.Cryptography.BCrypt.dll中发生类型为“System.ArgumentException”的未处理异常
附加信息:无效的salt版本
根据PHP加密密码哈希验证WPF应用程序中用户输入的密码是否正确?从系统中,ArgumentException由以下逻辑引发:
if (salt[1] != '$') {
minor = salt[2];
if (minor != 'a' || salt[3] != '$') {
throw new ArgumentException("Invalid salt revision");
}
因此,引发异常的原因似乎是哈希不是BCrypt
支持的格式
,带有password\u BCRYPT
参数的password\u hash
返回一个以$2y$
开头的哈希值,而C
使用的BCRYPT
实现需要一个以$2a$
开头的哈希值
我建议使用不同的方法来生成散列
编辑:从系统中获得了一些有关发生这种情况的原因的好信息。ArgumentException由以下逻辑引发:
if (salt[1] != '$') {
minor = salt[2];
if (minor != 'a' || salt[3] != '$') {
throw new ArgumentException("Invalid salt revision");
}
因此,引发异常的原因似乎是哈希不是BCrypt
支持的格式
,带有password\u BCRYPT
参数的password\u hash
返回一个以$2y$
开头的哈希值,而C
使用的BCRYPT
实现需要一个以$2a$
开头的哈希值
我建议使用不同的方法来生成散列
编辑:有一些关于为什么会发生这种情况的好信息
static class ExtentionMetsodString
{
public static string ReplaceAt(this string str,int startIdx , string replaceStr)
{
StringBuilder strBuilder = new StringBuilder(str);
int length = replaceStr.Length;
strBuilder.Remove(startIdx, length);
strBuilder.Insert(startIdx, replaceStr);
return strBuilder.ToString();
}
}
用法
酷扩展方法
static class ExtentionMetsodString
{
public static string ReplaceAt(this string str,int startIdx , string replaceStr)
{
StringBuilder strBuilder = new StringBuilder(str);
int length = replaceStr.Length;
strBuilder.Remove(startIdx, length);
strBuilder.Insert(startIdx, replaceStr);
return strBuilder.ToString();
}
}
用法
很酷谢谢,这澄清了很多。在您编辑的Github线程之后,我将我的C#应用程序中的
password\u hash
更改为$2y$
,结果为TRUE。因此,为了避免在C#中硬编码哈希前缀替换,我应该只在服务器端或客户端计算机上设置并验证密码哈希
,对吗?理想情况下,您希望在客户端生成哈希,并只在服务器端验证。如果您在客户端和webui上都注册,PHP和C#将生成不同的BCrypt哈希。在C#中,只需将$2y$替换为$2a$,散列就可以验证。或者另一种发送密码和验证的方法。@KalebKlein是的,我可以看出替换前缀是有效的,但这是正确的方法吗?至少是有效的方法。PHP
实现生成具有不同前缀的散列,因为早期版本(使用$2a$
前缀)存在错误;一旦bug被修复,他们就改变前缀来区分好的和有bug的散列。但是,后端(C#实现)从未出现过此错误,因此它仍然会查找前缀为$2a$
的哈希值。但是一个固定的($2y$
)PHP
散列与普通($2a$
)C#
散列完全相同,因此替换前缀将解决兼容性问题。谢谢,这澄清了很多问题。在您编辑的Github线程之后,我将我的C#应用程序中的password\u hash
更改为$2y$
,结果为TRUE。因此,为了避免在C#中硬编码哈希前缀替换,我应该只在服务器端或客户端计算机上设置并验证密码哈希
,对吗?理想情况下,您希望在客户端生成哈希,并只在服务器端验证。如果您在客户端和webui上都注册,PHP和C#将生成不同的BCrypt哈希。在C#中,只需将$2y$替换为$2a$,散列就可以验证。或者另一种发送密码和验证的方法。@KalebKlein是的,我可以看出替换前缀是有效的,但这是正确的方法吗?至少是有效的方法。PHP
实现生成具有不同前缀的散列,因为早期版本(使用$2a$
前缀)存在错误;一旦bug被修复,他们就改变前缀来区分好的和有bug的散列。但是,后端(C#实现)从未出现过此错误,因此它仍然会查找前缀为$2a$
的哈希值。但是固定的($2y$
)PHP
散列与普通($2a$
)C#
散列完全相同,因此替换前缀将解决兼容性问题。请不要定义salt。让密码\u hash()
为您生成它。PHP7中不推荐使用此参数。请不要定义salt。让密码\u hash()
为您生成它。PHP7中不推荐使用此参数。