using Microsoft.AspNetCore.DataProtection; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase; /// Versioned protection of complete protocol JSON, including nested credentials. public sealed class DataConnectionSecretConverter(IDataProtector protector) : ValueConverter( value => value == null ? null : Protect(protector, value), value => value == null ? null : Unprotect(protector, value)) { internal const string Prefix = "dp:protocol:v1:"; internal const string Purpose = EncryptedStringConverter.ProtectorPurpose + ".DataConnection"; /// Encrypts plaintext protocol JSON and tags it with the versioned prefix. /// The data protector to encrypt with. /// The plaintext to protect. /// The prefixed protected string. internal static string Protect(IDataProtector protector, string plaintext) => Prefix + protector.Protect(plaintext); /// Decrypts a stored, versioned protected value. /// The data protector to decrypt with. /// The stored value, which must carry the versioned prefix. /// The decrypted plaintext. internal static string Unprotect(IDataProtector protector, string stored) => stored.StartsWith(Prefix, StringComparison.Ordinal) ? protector.Unprotect(stored[Prefix.Length..]) : throw new InvalidOperationException("Protocol configuration requires the startup encryption upgrade before it can be read."); }