使用EF Core 2.2使用SQL Server DECRYPTBYKEY解密字符串

问题描述 投票:0回答:1

基本上,我有一个具有加密字符串的POCO模型。使用EF core 2.2。

我们使用DECRYPTBYKEY来使用SYMMETRIC KEY解密字符串。

我正在使用DBSet.FromSQL传递SQL查询,该查询调用打开对称密钥,获取包括解密值,关闭对称密钥的数据。

FromSQL仅允许您单独带回实体而不是字符串。

我尝试在模型上添加解密的字符串值,然后尝试在FromSQL查询中进行设置。

[当存储库DBSet中没有任何包含时,实际上填充为OK。

[当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; }
    }
c# sql-server entity-framework-core asp.net-core-2.2
1个回答
1
投票

根据我的收集,您可能仍想使用自定义getter / setter引入[NotMapped]属性:

class Model {
    public string Encrypted {get;set}
    [NotMapped]
    public string Decrypted {
    get { return Decrypt(Encrypted);}
   set { Encrypted = Encrypt(value);}
   }
}

当然,您需要提供加密/解密的实现

© www.soinside.com 2019 - 2024. All rights reserved.