Add UnprotectKeysWithAnyCertificate
This commit is contained in:
parent
3d30ea8249
commit
70dcbf6ed6
|
|
@ -320,6 +320,33 @@ namespace Microsoft.AspNetCore.DataProtection
|
|||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures certificates which can be used to decrypt keys loaded from storage.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param>
|
||||
/// <param name="certificates">Certificates that can be used to decrypt key data.</param>
|
||||
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
|
||||
public static IDataProtectionBuilder UnprotectKeysWithAnyCertificate(this IDataProtectionBuilder builder, params X509Certificate2[] certificates)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.Services.Configure<XmlKeyDecryptionOptions>(o =>
|
||||
{
|
||||
if (certificates != null)
|
||||
{
|
||||
foreach (var certificate in certificates)
|
||||
{
|
||||
o.AddKeyDecryptionCertificate(certificate);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures keys to be encrypted with Windows DPAPI before being persisted to
|
||||
/// storage. The encrypted key will only be decryptable by the current Windows user account.
|
||||
|
|
|
|||
|
|
@ -171,16 +171,16 @@ namespace Microsoft.AspNetCore.DataProtection
|
|||
|
||||
WithUniqueTempDirectory(directory =>
|
||||
{
|
||||
// Step 1: directory should be completely empty
|
||||
directory.Create();
|
||||
// Step 1: directory should be completely empty
|
||||
directory.Create();
|
||||
Assert.Empty(directory.GetFiles());
|
||||
|
||||
// Step 2: instantiate the system and round-trip a payload
|
||||
var protector = DataProtectionProvider.Create(directory, certificate).CreateProtector("purpose");
|
||||
// Step 2: instantiate the system and round-trip a payload
|
||||
var protector = DataProtectionProvider.Create(directory, certificate).CreateProtector("purpose");
|
||||
Assert.Equal("payload", protector.Unprotect(protector.Protect("payload")));
|
||||
|
||||
// Step 3: validate that there's now a single key in the directory and that it's is protected using the certificate
|
||||
var allFiles = directory.GetFiles();
|
||||
// Step 3: validate that there's now a single key in the directory and that it's is protected using the certificate
|
||||
var allFiles = directory.GetFiles();
|
||||
Assert.Single(allFiles);
|
||||
Assert.StartsWith("key-", allFiles[0].Name, StringComparison.OrdinalIgnoreCase);
|
||||
string fileText = File.ReadAllText(allFiles[0].FullName);
|
||||
|
|
@ -189,6 +189,40 @@ namespace Microsoft.AspNetCore.DataProtection
|
|||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void System_CanUnprotectWithCert()
|
||||
{
|
||||
var filePath = Path.Combine(GetTestFilesPath(), "TestCert2.pfx");
|
||||
var certificate = new X509Certificate2(filePath, "password");
|
||||
|
||||
WithUniqueTempDirectory(directory =>
|
||||
{
|
||||
// Step 1: directory should be completely empty
|
||||
directory.Create();
|
||||
Assert.Empty(directory.GetFiles());
|
||||
|
||||
// Step 2: instantiate the system and create some data
|
||||
var protector = DataProtectionProvider
|
||||
.Create(directory, certificate)
|
||||
.CreateProtector("purpose");
|
||||
|
||||
var data = protector.Protect("payload");
|
||||
|
||||
// Step 3: validate that there's now a single key in the directory and that it's is protected using the certificate
|
||||
var allFiles = directory.GetFiles();
|
||||
Assert.Single(allFiles);
|
||||
Assert.StartsWith("key-", allFiles[0].Name, StringComparison.OrdinalIgnoreCase);
|
||||
string fileText = File.ReadAllText(allFiles[0].FullName);
|
||||
Assert.DoesNotContain("Warning: the key below is in an unencrypted form.", fileText, StringComparison.Ordinal);
|
||||
Assert.Contains("X509Certificate", fileText, StringComparison.Ordinal);
|
||||
|
||||
// Step 4: setup a second system and validate it can decrypt keys and unprotect data
|
||||
var unprotector = DataProtectionProvider.Create(directory,
|
||||
b => b.UnprotectKeysWithAnyCertificate(certificate));
|
||||
Assert.Equal("payload", unprotector.CreateProtector("purpose").Unprotect(data));
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs a test and cleans up the temp directory afterward.
|
||||
/// </summary>
|
||||
|
|
|
|||
Loading…
Reference in New Issue