Skip to content

Instantly share code, notes, and snippets.

@KarateJB
Last active January 13, 2020 09:24
Show Gist options
  • Save KarateJB/c1c1f3f7e200a08913a510a3872db261 to your computer and use it in GitHub Desktop.
Save KarateJB/c1c1f3f7e200a08913a510a3872db261 to your computer and use it in GitHub Desktop.
[ASP.NET Core] Data Protection with TripleDES
[AllowAnonymous]
[Route("[controller]")]
[ApiExplorerSettings(IgnoreApi = true)]
public class HomeController : Controller
{
private readonly ILogger<HomeController> logger = null;
private readonly IDataProtectService cipher = null;
/// <summary>
/// Constructor
/// </summary>
public HomeController(
IDataProtectService cipher,
ILogger<HomeController> logger)
{
this.cipher = cipher;
this.logger = logger;
}
/// <summary>
/// Index
/// </summary>
[Route("Index")]
public ActionResult Index()
{
var encryptedText = this.cipher.Encrypt("This is for test. 這是為了測試!");
var decryptedText = this.cipher.Decrypt(encryptedText);
return this.View();
}
}
/// <summary>
/// Interface for Data Protection
/// </summary>
public interface IDataProtectService
{
/// <summary>
/// Encrypt
/// </summary>
/// <param name="input">Input</param>
/// <returns>Encrypted output</returns>
string Encrypt(string input);
/// <summary>
/// Decrypt
/// </summary>
/// <param name="cipherText">Encrpted input</param>
/// <returns>Decrypted output</returns>
string Decrypt(string cipherText);
}
/// <summary>
/// Data Protect Service
/// </summary>
public class DataProtectService : IDataProtectService
{
private const string Purpose = "CloutTis.Cipher.v1";
private readonly IDataProtectionProvider dataProtectionProvider = null;
private readonly ILogger<DataProtectService> logger = null;
public DataProtectService(
IDataProtectionProvider dataProtectionProvider,
ILogger<DataProtectService> logger)
{
this.dataProtectionProvider = dataProtectionProvider;
this.logger = logger;
}
public string Encrypt(string input)
{
var protector = this.dataProtectionProvider.CreateProtector(Purpose);
return protector.Protect(input);
}
public string Decrypt(string cipherText)
{
var protector = this.dataProtectionProvider.CreateProtector(Purpose);
return protector.Unprotect(cipherText);
}
}
/// <summary>
/// RedisXmlRepository
/// </summary>
public class RedisXmlRepository : IXmlRepository, IDisposable
{
private readonly string redisListKey = string.Empty;
private readonly ILogger<RedisXmlRepository> logger = null;
private readonly RedisService redis = null;
/// <summary>
/// Constructor
/// </summary>
/// <param name="redis">RedisService</param>
/// <param name="logger">Logger</param>
public RedisXmlRepository(RedisService redis, ILogger<RedisXmlRepository> logger)
{
this.redisListKey = RedisKeyFactory.KeyVault;
this.redis = redis;
this.logger = logger;
}
/// <summary>
/// Get all elements
/// </summary>
/// <returns>XElement readonly collection</returns>
public IReadOnlyCollection<XElement> GetAllElements()
{
var database = this.redis.Database;
var keys = this.redis.Database.ListRange(this.redisListKey, 0);
var elements = new List<XElement>();
if (keys != null && keys.Length > 0)
{
foreach (var key in keys)
{
elements.Add(XElement.Parse(key));
}
}
return elements.AsReadOnly();
}
/// <summary>
/// Store element to Redis hash
/// </summary>
/// <param name="element">XElement</param>
/// <param name="friendlyName">Name</param>
public void StoreElement(XElement element, string friendlyName)
{
if (element == null)
{
throw new ArgumentNullException(nameof(element));
}
if (string.IsNullOrEmpty(friendlyName))
{
friendlyName = Guid.NewGuid().ToString();
}
this.redis.Database.HashSet(this.redisListKey, friendlyName, element.ToString());
}
/// <summary>
/// Dispose
/// </summary>
public void Dispose()
{
}
}
services.AddDataProtection(options => options.ApplicationDiscriminator = "CloudTis")
.SetApplicationName("CloudTis") // Shared application name
.DisableAutomaticKeyGeneration()
////.PersistKeysToStackExchangeRedis(redisConnection, RedisKeyFactory.KeyVault)
.PersistKeysToFileSystem(new DirectoryInfo(@"C:\temp\keys\"))
.UseCustomCryptographicAlgorithms(
new ManagedAuthenticatedEncryptorConfiguration()
{
// A type that subclasses SymmetricAlgorithm
EncryptionAlgorithmType = typeof(TripleDESCng), // Or TripleDESCryptoServiceProvider
// Specified in bits
EncryptionAlgorithmKeySize = 192, // 128|192 / 8 = 16|24 bytes
// A type that subclasses KeyedHashAlgorithm
ValidationAlgorithmType = typeof(HMACSHA256)
});
////.ProtectKeysWithDpapi(); // Use Machine key to encrypt the keys
////.AddKeyEscrowSink(sp => new MyKeyEscrowSink(sp));
services.AddScoped<IXmlRepository, RedisXmlRepository>();
services.AddScoped<IDataProtectService, DataProtectService>();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment