Skip to content

Instantly share code, notes, and snippets.

@NtFreX
Created January 19, 2018 09:32
Show Gist options
  • Save NtFreX/dfa9712e4fc2b65c30cb9549e38e6d73 to your computer and use it in GitHub Desktop.
Save NtFreX/dfa9712e4fc2b65c30cb9549e38e6d73 to your computer and use it in GitHub Desktop.
/*
public void Configure()
{
services.Configure<CertificateBasedDataProtectorOptions>(x => ...)
services.TryAddSingleton<IDataProtectionProvider, CertificateBasedDataProtectionProvider>();
}
*/
public sealed class CertificateBasedDataProtectionProvider : IDataProtectionProvider
{
private readonly ILogger<CertificateBasedDataProtector> _logger;
private readonly IOptions<CertificateBasedDataProtectorOptions> _jwtBasedDataProtectorOptions;
public CertificateBasedDataProtectionProvider(ILogger<CertificateBasedDataProtector> logger, IOptions<CertificateBasedDataProtectorOptions> jwtBasedDataProtectorOptions)
{
_logger = logger;
_jwtBasedDataProtectorOptions = jwtBasedDataProtectorOptions;
}
public IDataProtector CreateProtector(string purpose)
=> new CertificateBasedDataProtector(_logger, _jwtBasedDataProtectorOptions, purpose);
}
public class CertificateBasedDataProtector : IDataProtector
{
private readonly ILogger<CertificateBasedDataProtector> _logger;
private readonly IOptions<CertificateBasedDataProtectorOptions> _jwtBasedDataProtectorOptions;
public string Purpose { get; }
public CertificateBasedDataProtector(ILogger<CertificateBasedDataProtector> logger, IOptions<CertificateBasedDataProtectorOptions> jwtBasedDataProtectorOptions, string purpose)
{
_logger = logger;
_jwtBasedDataProtectorOptions = jwtBasedDataProtectorOptions;
Purpose = purpose;
}
public IDataProtector CreateProtector(string purpose)
{
if (string.IsNullOrEmpty(purpose))
{
throw new ArgumentNullException(nameof(purpose));
}
return new CertificateBasedDataProtector(_logger, _jwtBasedDataProtectorOptions, purpose);
}
public byte[] Protect(byte[] plaintext)
{
using (var rsa = _jwtBasedDataProtectorOptions.Value.Certificate.GetRSAPrivateKey())
{
var signature = rsa.SignData(plaintext, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
return signature.Concat(plaintext).ToArray();
}
}
public byte[] Unprotect(byte[] protectedData)
{
var signatureSize = 128 / 4;
var data = protectedData.Skip(signatureSize).ToArray();
if (Protect(data) != protectedData)
return new byte[] { };
return data;
}
}
public class CertificateBasedDataProtectorOptions
{
public X509Certificate2 Certificate { get; set; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment