fix: 修复BCrypt加密算法存在的生成salt问题。

main
NoahLan 6 months ago
parent f3382f9c8e
commit 808ec6b60a

@ -1,40 +1,47 @@
using System.Security.Cryptography;
using System.Text;
namespace NPin.Framework.Core.Crypt.BCrypt;
public static class BCrypt
{
public static byte[] Generate(string password, string salt, int cost)
{
var passBytes = Encoding.UTF8.GetBytes(password);
var saltBytes = Encoding.UTF8.GetBytes(salt);
return Org.BouncyCastle.Crypto.Generators.BCrypt.Generate(passBytes, saltBytes, cost);
}
public static string GenerateSalt()
{
var buf = new byte[16];
using var rand = RandomNumberGenerator.Create();
rand.GetBytes(buf);
return Convert.ToBase64String(buf);
}
/// <summary>
/// 检查密码是否正确
/// 通过再次生成一次密码匹配
/// </summary>
/// <param name="encrypt"></param>
/// <param name="password"></param>
/// <param name="salt"></param>
/// <param name="cost"></param>
/// <returns></returns>
public static bool Check(string encrypt, string password, string salt, int cost)
{
var passStr = Generate(password, salt, cost).ToString();
return string.Equals(encrypt, passStr);
}
using System.Security.Cryptography;
using System.Text;
using BBCrypt = Org.BouncyCastle.Crypto.Generators.BCrypt;
namespace NPin.Framework.Core.Crypt.BCrypt;
public static class BCrypt
{
public static byte[] Generate(string password, string salt, int cost = 4)
{
var passBytes = BBCrypt.PasswordToByteArray(password.ToCharArray());
var saltBytes = Convert.FromBase64String(salt);
return BBCrypt.Generate(passBytes, saltBytes, cost);
}
public static string GenerateStr(string password, string salt, int cost = 4)
{
var bytes = Generate(password, salt, cost);
return Convert.ToBase64String(bytes);
}
public static string GenerateSalt()
{
var buf = new byte[16];
using var rand = RandomNumberGenerator.Create();
rand.GetBytes(buf);
return Convert.ToBase64String(buf, 0, 16);
}
/// <summary>
/// 检查密码是否正确
/// 通过再次生成一次密码匹配
/// </summary>
/// <param name="encrypt"></param>
/// <param name="password"></param>
/// <param name="salt"></param>
/// <param name="cost"></param>
/// <returns></returns>
public static bool Check(string encrypt, string password, string salt, int cost)
{
var passStr = GenerateStr(password, salt, cost);
return string.Equals(encrypt, passStr);
}
}

@ -1,4 +1,5 @@
using NPin.Framework.Core.Crypt.BCrypt;
using System.Text;
using NPin.Framework.Core.Crypt.BCrypt;
using NPin.Framework.SqlSugarCore.Abstractions.Data;
using NPin.Framework.Upms.Domain.Entities.ValueObjects;
using NPin.Framework.Upms.Domain.Shared.Enums;
@ -28,8 +29,8 @@ public class UserEntity : Entity<Guid>, ISoftDelete, IAuditedObject, IEnabled, I
[SugarColumn(ColumnDescription = "昵称")]
public string? Nickname { get; set; }
[SugarColumn(ColumnDescription = "密码", IsOwnsOne = true)]
public EncryptPasswordValueObject? EncryptPassword { get; set; } = new EncryptPasswordValueObject();
[SugarColumn(IsOwnsOne = true)]
public EncryptPasswordValueObject EncryptPassword { get; set; } = new();
[SugarColumn(ColumnDescription = "简介")]
public string? Introduction { get; set; }
@ -50,12 +51,12 @@ public class UserEntity : Entity<Guid>, ISoftDelete, IAuditedObject, IEnabled, I
/// <summary>
/// 逻辑删除
/// </summary>
public bool IsDeleted { get; }
public bool IsDeleted { get; set; }
public DateTime CreationTime { get; } = DateTime.Now;
public Guid? CreatorId { get; }
public DateTime? LastModificationTime { get; }
public Guid? LastModifierId { get; }
public DateTime CreationTime { get; set; } = DateTime.Now;
public Guid? CreatorId { get; set; }
public DateTime? LastModificationTime { get; set; }
public Guid? LastModifierId { get; set; }
/// <summary>
/// 是否启用
@ -123,10 +124,10 @@ public class UserEntity : Entity<Guid>, ISoftDelete, IAuditedObject, IEnabled, I
{
// 若传入密码无值则使用原本Password
// 若原本Password依然无值则抛出参数异常
password ??= EncryptPassword?.Password ?? throw new ArgumentNullException(nameof(EncryptPassword.Password));
password ??= EncryptPassword.Password ?? throw new ArgumentNullException(nameof(EncryptPassword.Password));
EncryptPassword.Salt = BCrypt.GenerateSalt();
EncryptPassword.Password = BCrypt.Generate(password, EncryptPassword.Salt, 0).ToString()!;
EncryptPassword.Password = BCrypt.GenerateStr(password, EncryptPassword.Salt, 10);
return this;
}
@ -139,11 +140,11 @@ public class UserEntity : Entity<Guid>, ISoftDelete, IAuditedObject, IEnabled, I
/// <exception cref="ArgumentNullException"></exception>
public bool CheckPassword(string password)
{
if (EncryptPassword?.Salt is null)
if (EncryptPassword.Salt is null)
{
throw new ArgumentNullException(nameof(EncryptPassword.Salt));
}
return BCrypt.Check(EncryptPassword.Password, password, EncryptPassword.Salt, 0);
return BCrypt.Check(EncryptPassword.Password, password, EncryptPassword.Salt, 10);
}
}
Loading…
Cancel
Save