【发布时间】:2020-03-30 04:34:33
【问题描述】:
基本上我有一个带有加密字符串的 POCO 模型。使用 EF 核心 2.2。
我们使用 DECRYPTBYKEY 使用 SYMMETRIC KEY 解密字符串。
我正在使用 DBSet.FromSQL 传入调用打开对称密钥的 SQL 查询,获取包含解密值的数据,关闭对称密钥。
FromSQL 只允许你返回一个实体而不是一个字符串。
我尝试在模型上添加一个解密的字符串值,然后尝试在 FromSQL 查询中设置它。
当存储库 DBSet 没有任何 .Include 时,这实际上会填充。
当 DBSet 确实有 .Include (在外键表上过滤 DBSet)时,会出现运行时错误,抱怨解密的字符串不是数据库表上的列 - 当然不是。所以拥有 .Include 是首先调用基表上的 SQL。
如果我将 [NotMapped] 属性放在解密的字符串列上,那么当 FromSQL 查询运行时它不会填充它。
那么如何在不使用 [NotMapped] 而是在 DBSet 上使用 .Include 的情况下使用这个解密的字符串列?
我已经添加了代码,以便您可以看到更多问题。无法按照一个答案中的建议在模型上添加 Decrypt 的实现。 Decrypt 方法需要 DbSet 调用 FromSQL。 DbSet 起源于 ConcreteRepository。我也看不到调用临时 SQL 查询来返回 1 个字符串。
从原始 SQL (SQL Server) 截取
OPEN SYMMETRIC KEY {1} DECRYPTION BY PASSWORD = '{2}';
SELECT * , --other fields
CONVERT(VARCHAR(60), DECRYPTBYKEY(A.Encrypted)) AS Decrypted
FROM dbo.Model A
JOIN table2 t2 ON ...
JOIN table3 t3 ON ...
WHERE A.Id= 123
CLOSE SYMMETRIC KEY {1};",
具体存储库
public async Task<IEnumerable<Model>> GetAllById(int id)
{
var filteredSet = Set.Where(x => x.Id == id)
.Include(x => x.Table2)
.Where(x => x.Table2.IsSomething).ToList();
var models = filteredSet.Select(f =>
GetDecryptValue($"Id = {f.Id}");
return models;
}
基础存储库
protected DbSet<TEntity> Set => _dbContext.Set<TEntity>();
public virtual TEntity GetDecryptValue(string filterCriteria)
{
string buildSelectStmt = $"SELECT TOP 1 Encrypted FROM Model";
string buildSelectStmt2 = $"SELECT *, CONVERT(VARCHAR(MAX), DECRYPTBYKEY(@Value)) AS Decrypted FROM Model";
buildSelectStmt = $"{buildSelectStmt} WHERE {filterCriteria}";
buildSelectStmt2 = $"{buildSelectStmt2} WHERE {filterCriteria}";
string sql = string.Format(@"
DECLARE @Value NVARCHAR(MAX)
SET @Value = ({0});
OPEN SYMMETRIC KEY {1} DECRYPTION BY PASSWORD = '{2}';
{3};
CLOSE SYMMETRIC KEY {1};",
buildSelectStmt, SymmetricKeyName, SymmetricKeyPassword, buildSelectStmt2);
var result = Set.FromSql(sql);
return result.FirstOrDefault();
}
型号
public partial class Model
{
public int Id { get; set; }
public string Encrypted { get; set; }
[NotMapped]
public string Decrypted { get; set; }
}
【问题讨论】:
-
看起来倾向于SQL injection。
标签: c# sql-server entity-framework-core asp.net-core-2.2