Search code examples
azureiisazure-keyvault

Transfer encrypted dataprotection keys from a windows vm to azure keyvault


I have a site with Data Protection keys stored in the registry (due to loadUserProfile being set to false in IIS).

How can I transfer these keys to Azure Key Vault without causing users to be logged out when the site starts using Key Vault for Data Protection?

The azure keyvault requires pem files to import and the keys I have from the registry are encrypted with dpapi.

Sample key from the dataprotection ssid

<key id="468ac09b-dc55-4491-908d-5eb77b5ffa69" version="1">
  <creationDate>2024-07-24T07:26:24.0110669Z</creationDate>
  <activationDate>2024-07-25T13:31:44.1979108Z</activationDate>
  <expirationDate>2024-10-22T07:26:23.9818278Z</expirationDate>
  <descriptor deserializerType="Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60">
    <descriptor>
      <encryption algorithm="AES_256_CBC" />
      <validation algorithm="HMACSHA256" />
      <encryptedSecret decryptorType="Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiXmlDecryptor, Microsoft.AspNetCore.DataProtection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60" xmlns="http://schemas.asp.net/2015/03/dataProtection">
        <encryptedKey xmlns="">
          <!-- This key is encrypted with Windows DPAPI. -->
          <value>AQAAANCMnd8BFdERjHoAwE/....I19Nf2RdYA==</value>
        </encryptedKey>
      </encryptedSecret>
    </descriptor>
  </descriptor>
</key>

After the comments tried with the following code in the same site but had no luck

var buffer = Convert.FromBase64String(AQAAANCMnd8BFdERjHoAwE/....I19Nf2RdYA==);
result = ProtectedData.Unprotect(buffer, null, DataProtectionScope.CurrentUser);

Solution

  • The following answer in github presented a relative easy way to do the transfer, couldn't find anything better:

    Moving keys that are encrypted using the default mechanism is probably something that will never be supported / documented because of how fragile and error-prone it is. The easiest and most fool-proof way to migrate a live web app would be what @blowdart suggests: configure the Data Protection system to use the file system as the key repository, and also configure it to use an X.509 certificate to protect keys at rest. You can even do this using a console application and watch the key files get dropped on disk. Then change your web app's startup config to use the same repository / protection mechanism. After a few days (default 48 hours) the key rotation policy will kick in and the web application will start using the new keys on disk rather than the old keys from the registry. (The old keys will still be able to decrypt existing auth tokens, but they won't be used to issue new auth tokens.) Wait a few more days to make sure that all existing logged-on users have had their auth tokens refreshed. Then you can move the web application - keys and all - to the new machine. You'll lose the ability to decrypt with the old keys, but this shouldn't result in service interruption since all logged-on users should have had their auth tokens refreshed over the waiting period.