在写入/读取到C#mongo db时加密/解密属性 [英] Encrypt/Decrypt property while writing/reading to c# mongo db

查看:81
本文介绍了在写入/读取到C#mongo db时加密/解密属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只需布置一下我拥有的所有信息即可:

简而言之,我正在寻找(字面上)确切的东西,例如

属性:

[AttributeUsage(AttributeTargets.Property)]
public class MongoEncryptAttribute : BsonSerializerAttribute
{
    public MongoEncryptAttribute()
    {
        SerializerType = typeof(MongoEncryptSerializer);
    }
}

自定义序列化器:

public interface IMongoEncryptSerializer : IBsonSerializer<EncryptedString>{ }

public class MongoEncryptSerializer : SerializerBase<EncryptedString>, IMongoEncryptSerializer
{
    private readonly string _encryptionKey;

    public MongoEncryptSerializer(IConfiguration configuration)
    {
        _encryptionKey = configuration.GetSection("MongoDb")["EncryptionKey"];
    }

    public override EncryptedString Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        var encryptedString = context.Reader.ReadString();
        return AesThenHmac.SimpleDecryptWithPassword(encryptedString, _encryptionKey);
    }

    public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, EncryptedString value)
    {
        var encryptedString = AesThenHmac.SimpleEncryptWithPassword(value, _encryptionKey);
        context.Writer.WriteString(encryptedString);
    }
}

未清项目:

  1. 使用DI(香草.net核心DI)获取串行器.在引导方法中想到类似BsonSerializer.RegisterSerializer(type,serializer)之类的东西,在该方法中我可以访问服务集合并执行GetInstance,但是随后我需要string SocialSecurityNumber才能使用自定义类型(也许是SecureString?)

  2. 在序列化程序中使用DI来获取密钥(最初是从IConfiguration/appsettings.json ,然后最终是从Azure KeyVault(对我来说是全新的蠕虫病毒))和EncryptionProvider

  3. 确定性加密以进行搜索. AesThenHmac来自此流行的帖子.我可以在当前的实现中很好地存储和检索数据.但是,为了搜索SSN,我需要确定性加密,而该库没有提供这种加密.

解决方案

我的解决方案:

型号:

public class Patient
{
    //comes from the client as XXXXXXXXX, RegEx: "([0-9]{9})"
    public EncryptedString SocialSecurityNumber { get; set; }  
}

自定义类型:

public class EncryptedString
{
    private readonly string _value;

    public EncryptedString(string value)
    {
        _value = value;
    }

    public static implicit operator string(EncryptedString s)
    {
        return s._value;
    }

    public static implicit operator EncryptedString(string value)
    {
        if (value == null)
            return null;

        return new EncryptedString(value);
    }
}

序列化器(使用确定性加密):

public interface IEncryptedStringSerializer : IBsonSerializer<EncryptedString> {} 

public class EncryptedStringSerializer : SerializerBase<EncryptedString>, IEncryptedStringSerializer
{
    private readonly IDeterministicEncrypter _encrypter;
    private readonly string _encryptionKey;

    public EncryptedStringSerializer(IConfiguration configuration, IDeterministicEncrypter encrypter)
    {
        _encrypter = encrypter;
        _encryptionKey = configuration.GetSection("MongoDb")["EncryptionKey"];
    }

    public override EncryptedString Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        var encryptedString = context.Reader.ReadString();
        return _encrypter.DecryptStringWithPassword(encryptedString, _encryptionKey);
    }

    public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, EncryptedString value)
    {
        var encryptedString = _encrypter.EncryptStringWithPassword(value, _encryptionKey);
        context.Writer.WriteString(encryptedString);
    }
}

注册序列化器:

collection.AddScoped<IEncryptedStringSerializer, EncryptedStringSerializer>();
//then later...
BsonSerializer.RegisterSerializer<EncryptedString>(sp.GetService<IEncryptedStringSerializer>());

Just going to lay out all the info i have:

In short, I am looking for something exactly (literally) like this but compatible with ASP Core (2.2) and the C# MongoDB Driver (2.7).

This seems like such a common requirement, I am very surprised i can't find anything already built.

Here is what i have so far:

Model:

public class Patient
{
    //comes from the client as XXXXXXXXX, RegEx: "([0-9]{9})"
    //[MongoEncrypt]
    public EncryptedString SocialSecurityNumber { get; set; }  
}

Attribute:

[AttributeUsage(AttributeTargets.Property)]
public class MongoEncryptAttribute : BsonSerializerAttribute
{
    public MongoEncryptAttribute()
    {
        SerializerType = typeof(MongoEncryptSerializer);
    }
}

Custom Serializer:

public interface IMongoEncryptSerializer : IBsonSerializer<EncryptedString>{ }

public class MongoEncryptSerializer : SerializerBase<EncryptedString>, IMongoEncryptSerializer
{
    private readonly string _encryptionKey;

    public MongoEncryptSerializer(IConfiguration configuration)
    {
        _encryptionKey = configuration.GetSection("MongoDb")["EncryptionKey"];
    }

    public override EncryptedString Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        var encryptedString = context.Reader.ReadString();
        return AesThenHmac.SimpleDecryptWithPassword(encryptedString, _encryptionKey);
    }

    public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, EncryptedString value)
    {
        var encryptedString = AesThenHmac.SimpleEncryptWithPassword(value, _encryptionKey);
        context.Writer.WriteString(encryptedString);
    }
}

Open Items:

  1. Use DI (vanilla .net core DI) to get the Serializer. thinking of something like BsonSerializer.RegisterSerializer(type,serializer) in a bootstrap method where i can access the service collection and do a GetInstance but then i would need string SocialSecurityNumber to use a custom type (maybe SecureString?)

  2. Use DI in the serializer to get the key (initially from IConfiguration/appsettings.json and then ultimately from Azure KeyVault (whole new can of worms for me)) and the EncryptionProvider

  3. deterministic encryption for searching. AesThenHmac comes from this popular post. I can store and retrieve data back fine in its current implementation. But in order to search for SSNs, I need deterministic encryption which this lib does not provide.

解决方案

My Solution:

Model:

public class Patient
{
    //comes from the client as XXXXXXXXX, RegEx: "([0-9]{9})"
    public EncryptedString SocialSecurityNumber { get; set; }  
}

Custom Type:

public class EncryptedString
{
    private readonly string _value;

    public EncryptedString(string value)
    {
        _value = value;
    }

    public static implicit operator string(EncryptedString s)
    {
        return s._value;
    }

    public static implicit operator EncryptedString(string value)
    {
        if (value == null)
            return null;

        return new EncryptedString(value);
    }
}

Serializer(using Deterministic Encryption):

public interface IEncryptedStringSerializer : IBsonSerializer<EncryptedString> {} 

public class EncryptedStringSerializer : SerializerBase<EncryptedString>, IEncryptedStringSerializer
{
    private readonly IDeterministicEncrypter _encrypter;
    private readonly string _encryptionKey;

    public EncryptedStringSerializer(IConfiguration configuration, IDeterministicEncrypter encrypter)
    {
        _encrypter = encrypter;
        _encryptionKey = configuration.GetSection("MongoDb")["EncryptionKey"];
    }

    public override EncryptedString Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        var encryptedString = context.Reader.ReadString();
        return _encrypter.DecryptStringWithPassword(encryptedString, _encryptionKey);
    }

    public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, EncryptedString value)
    {
        var encryptedString = _encrypter.EncryptStringWithPassword(value, _encryptionKey);
        context.Writer.WriteString(encryptedString);
    }
}

Registering the serializer:

collection.AddScoped<IEncryptedStringSerializer, EncryptedStringSerializer>();
//then later...
BsonSerializer.RegisterSerializer<EncryptedString>(sp.GetService<IEncryptedStringSerializer>());

这篇关于在写入/读取到C#mongo db时加密/解密属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆