using Newtonsoft.Json; using System.Collections.Generic; namespace Pilz.Cryptography; [JsonConverter(typeof(Json.Converters.SecureStringJsonConverter))] public class SecureString { public static ICrypter DefaultCrypter { get; set; } public ICrypter Crypter { get; set; } public string EncryptedValue { get; set; } public string Value { get => GetCrypter()?.Decrypt(EncryptedValue); set => EncryptedValue = GetCrypter().Encrypt(value); } [JsonConstructor] private SecureString(JsonConstructorAttribute dummyAttribute) { } public SecureString() : this(string.Empty, true) { } public SecureString(string value, bool isEncrypted) : this(value, isEncrypted, null) { } public SecureString(string value, bool isEncrypted, ICrypter crypter) { Crypter = crypter; if (isEncrypted) EncryptedValue = value; else Value = value; } private ICrypter GetCrypter() { if (Crypter == null) { if (DefaultCrypter == null) DefaultCrypter = new SimpleStringCrypter(string.Empty); Crypter = DefaultCrypter; } return Crypter; } public override string ToString() => Value; public override bool Equals(object obj) { var @string = obj as SecureString; return @string != null && EncryptedValue == @string.EncryptedValue; } public override int GetHashCode() { return -2303024 + EqualityComparer.Default.GetHashCode(EncryptedValue); } public static implicit operator string(SecureString value) => value?.Value; public static implicit operator SecureString(string value) => new SecureString(value, false); public static bool operator ==(SecureString left, SecureString right) => left?.EncryptedValue == right?.EncryptedValue; public static bool operator !=(SecureString left, SecureString right) => left?.EncryptedValue != right?.EncryptedValue; }