我正在使用Entity Framework Code First Migrations,我希望我的Configuration.cs文件中的Seed方法为我创建一个默认用户。我将散列的用户密码作为 varbinary(64) 存储在数据库中,将 salt 作为 varbinary(16) 存储。我复制了现有用户的哈希和盐,因此种子方法可以在创建默认用户时使用它。我遇到的问题是将密码哈希和盐的字符串表示形式转换为相应的 sql 数据类型。这是我到目前为止所尝试的:
string hashString = "0x81E09FC75CFAB13F54DF1266ADCA53B9FAE45C1D80655C61DE88057846F9B61DC3ED257F2C7D7B73826F9DC0FFA 5FF987B1A594FD9DAE3DC492F5815E989CD34";
string saltString = "0x630FE0A0186365FF9CCBB0FA6161C08B";
Byte[] pbytes = Encoding.ASCII.GetBytes(hashString);
Byte[] sbytes = Encoding.ASCII.GetBytes(saltString);
context.Users.AddOrUpdate(p => p.FirstName,
new User
{
Id = Guid.NewGuid(),
FirstName = "John",
LastName = "Doe",
Username = "admin",
Email = "jdoe@test.com",
PasswordHash = pbytes,
PasswordSalt = sbytes,
RoleId = 1,
LastLoginDate = null
});
当我从包管理器控制台运行 update-database 时,我收到“一个或多个实体的验证失败”错误。只是为了测试一下,我复制了我的哈希代码并尝试使用它,它按预期工作。显然,我不想在我的种子方法中重用这段代码,所以我只需要一种方法来转换数据库会满意的字符串 int Byte[]。我已经包含了下面工作的代码。
byte[] saltBytes = new byte[16];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetNonZeroBytes(saltBytes);
byte[] plainTextBytes = System.Text.Encoding.UTF8.GetBytes("admin");
byte[] plainTextWithSaltBytes = new byte[plainTextBytes.Length + saltBytes.Length];
plainTextBytes.CopyTo(plainTextWithSaltBytes, 0);
saltBytes.CopyTo(plainTextWithSaltBytes, plainTextBytes.Length);
var hash = new SHA512Managed();
byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes);
context.Users.AddOrUpdate(p => p.FirstName,
new User
{
Id = Guid.NewGuid(),
FirstName = "John",
LastName = "Doe",
Username = "admin",
Email = "jdoe@test.com",
PasswordHash = hashBytes,
PasswordSalt = saltBytes,
RoleId = 1,
LastLoginDate = null
});