用framework.net重现Microsoft.AspNetCore.DataProtection的解密 4.8

Reproduce the decryption of Microsoft.AspNetCore.DataProtection with the framework.net 4.8

我只想在 .net 4.8 中重现 "Microsoft.AspNetCore.DataProtection" 中的解密部分。

它是为了能够与 .net 4.8 中的 webapi 共享秘密

.netCore 中的示例

UTF8Encoding _encodeur = new UTF8Encoding(false, true);
var services = new ServiceCollection();
services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo("c:\temp\secu"))
    .SetApplicationName("INTRANET");
var providerService = services.BuildServiceProvider();
var providerProtection = providerService.GetDataProtectionProvider();

var protector = providerProtection.CreateProtector("INTRANET");

var plaintext = "mon texte";
// PROTECT
var plaintextBytes = _encodeur.GetBytes(plaintext);
var protectBytes = protector.Protect(plaintextBytes);

// UNPROTECT
var unprotectBytes = protector.Unprotect(protectBytes);
var unprotectPlaintext = _encodeur.GetString(unprotectBytes);

文件包含主密钥

<?xml version="1.0" encoding="utf-8"?>
<key id="cd977748-5482-42a4-85e7-fb6138ef6b10" version="1">
  <creationDate>2020-02-12T10:04:08.28082Z</creationDate>
  <activationDate>2020-02-12T10:04:01.9592602Z</activationDate>
  <expirationDate>2020-05-12T10:04:01.9592602Z</expirationDate>
  <descriptor deserializerType="Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=2.2.0.0, Culture=neutral, PublicKeyToken=null">
    <descriptor>
      <encryption algorithm="AES_256_CBC" />
      <validation algorithm="HMACSHA256" />
      <masterKey p4:requiresEncryption="true" xmlns:p4="http://schemas.asp.net/2015/03/dataProtection">
        <!-- Warning: the key below is in an unencrypted form. -->
        <value>pkxdnaumouftFkYEZczl40Ah5stOxhRFoQWFNmHoGHwAxRcpgbnfNRvdWFhInrpG6l+obewxh0gT/4tkDBtxDQ==</value>
      </masterKey>
    </descriptor>
  </descriptor>
</key>

但是如果我按照这个示例进入 .net 4.8 How to decrypt an AES-256-CBC encrypted string

如何使用我的主密钥 pkxdnaumouftFkYEZczl40Ah5stOxhRFoQWFNmHoGHwAxRcpgbnfNRvdWFhInrpG6l+obewxh0gT/4tkDBtxDQ==

创建派生密钥 ivString 和 keyString
public static string Decrypt(string cipherData, string keyString, string ivString)
{
    byte[] key = Encoding.UTF8.GetBytes(keyString);
    byte[] iv  = Encoding.UTF8.GetBytes(ivString);

    try
    {
        using (var rijndaelManaged =
               new RijndaelManaged {Key = key, IV = iv, Mode = CipherMode.CBC})
        using (var memoryStream = 
               new MemoryStream(Convert.FromBase64String(cipherData)))
        using (var cryptoStream =
               new CryptoStream(memoryStream,
                   rijndaelManaged.CreateDecryptor(key, iv),
                   CryptoStreamMode.Read))
        {
            return new StreamReader(cryptoStream).ReadToEnd();
        }
    }
    catch (CryptographicException e)
    {
        Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
        return null;
    }
    // You may want to catch more exceptions here...
}

我找到了怎么做,你必须导入包 Microsoft.Owin.Security.Interop

包 .net 4.X

Microsoft.Owin.Security.Interop

包.netcore

Microsoft.AspNetCore.DataProtection

Microsoft.AspNetCore.TestHost 仅用于在 UnitTest 或控制台中进行测试

这是代码,.net Classic 和 .netCore 都一样

var services = new ServiceCollection();
services.AddDataProtection()
    .PersistKeysToSqlServer("INTRANET");// with custom datastore
// .PersistKeysToFileSystem(new DirectoryInfo("c:\temp\secu"));

var providerService = services.BuildServiceProvider();
var providerProtection = providerService.GetDataProtectionProvider();

var dataProtector = providerProtection.CreateProtector("INTRANET");
//var ticketFormat = new AspNetTicketDataFormat(new DataProtectorShim(dataProtector));

var plaintext = "mon texte";
var protectText = dataProtector.Protect(plaintext);
var unprotect = dataProtector.Unprotect(protectText);
Debug.Assert(plaintext == unprotect);