我将加密形式的电子邮件存储在数据库中,当用户想要注册时,我必须让所有用户和foreach
循环检查电子邮件地址,以确保新电子邮件不存在。
我发现我可以在表名like this example之后使用AsEnumerable()
。
我是否可以使用更优化的方法在linq查询中使用本地方法,而不需要选择所有实体?
答案 0 :(得分:2)
您可以将密文分为3部分,散列,加密,IV。 当您想要查询和搜索特定文本时,您可以对纯文本进行散列并在密文文本第1部分中搜索哈希并获取您的行。
这是asp.net的核心代码:
public static string CreateKey()
{
var alg = Aes.Create();
alg.KeySize = 256;
return Convert.ToBase64String(inArray: alg.Key);
}
public string EncryptAes(string inputText)
{
if (inputText == null) return null;
var hashing = new Hashing(text: inputText);
var hash = hashing.GetHash();
var inputBytes = Encoding.UTF8.GetBytes(s: inputText);
using (var ms = new MemoryStream())
{
var alg = Aes.Create();
var pdb = new Rfc2898DeriveBytes(password: _key, salt: alg.IV);
alg.Key = pdb.GetBytes(32);
alg.IV = pdb.GetBytes(16);
using (
var cs = new CryptoStream(stream: ms, transform: alg.CreateEncryptor(),
mode: CryptoStreamMode.Write)
)
{
cs.Write(buffer: inputBytes, offset: 0, count: inputBytes.Length);
}
return hash + Convert.ToBase64String(inArray: pdb.Salt) + Convert.ToBase64String(inArray: ms.ToArray());
}
}
public string DecryptAes(string inputText)
{
if (inputText == null) return null;
var inputBytes = Convert.FromBase64String(s: inputText.Substring(52));
var pdb = new Rfc2898DeriveBytes(password: _key,
salt: Convert.FromBase64String(s: inputText.Substring(28, 24)));
using (var ms = new MemoryStream())
{
var alg = Aes.Create();
alg.Key = pdb.GetBytes(32);
alg.IV = pdb.GetBytes(16);
using (
var cs = new CryptoStream(stream: ms, transform: alg.CreateDecryptor(), mode: CryptoStreamMode.Write)
)
{
cs.Write(buffer: inputBytes, offset: 0, count: inputBytes.Length);
}
return Encoding.UTF8.GetString(bytes: ms.ToArray());
}
}
散列功能:
public string GetHash()
{
using (var sha1 = SHA1.Create())
{
var hashedBytes = sha1.ComputeHash(buffer: Encoding.UTF8.GetBytes(s: _text));
return Convert.ToBase64String(inArray: hashedBytes).Replace(oldValue: "-", newValue: "");
}
}
public string GetHashFromEncryption(string text)
{
return text.Substring(0,28);
}
答案 1 :(得分:0)
要将Plaintext1与Ciphertext2进行比较,您有两种选择:
选项2您可以预先执行一次,然后将Ciphertext1作为查询参数的值传递。这可以回避你的问题。
但是,这只适用于可预测的腌制。如果你用随意的乱码盐,这将打败选项2.如果你不知道我的意思盐腌,那么你可能没有这个问题。