Fix Error CryptographicException: The payload was invalid.

Raymond Raymond event 2021-08-24 visibility 8,285
more_vert

When it comes to protect data, one direct way is to encrypt it by adopting certain cryptographic algorithm. In .NET, there are many encryption or decryption algorithms available to use. Like storing secrets in a container with a key, you don't want to expose that key to anyone else if you want to keep the secrets. In .NET Core or f.NET 5/6, data protection system provides quite a few approaches to secure the private key.

Different ways to secure the keys

On Azure, we can store the keys in Azure Key Vault; in other applications, we can persist the key to a disk that cannot be accessed by others. You can also upload the keys to a database via EntityFramework via DbContext so that only users who have access to the database can access the private key and use it to encrypt or decrypt messages. 

The following is one example:

services.AddDataProtection()
                .PersistKeysToDbContext<ApplicationDbContext>()
                .SetDefaultKeyLifetime(TimeSpan.FromDays(180));

The payload was invalid error

Exceptions can be thrown out using the above code snippet:

System.Security.Cryptography.CryptographicException: The payload was invalid.
         at Microsoft.AspNetCore.DataProtection.Cng.CbcAuthenticatedEncryptor.DecryptImpl(Byte* pbCiphertext, UInt32 cbCiphertext, Byte* pbAdditionalAuthenticatedData, UInt32 cbAdditionalAuthenticatedData)
         at Microsoft.AspNetCore.DataProtection.Cng.Internal.CngAuthenticatedEncryptorBase.Decrypt(ArraySegment`1 ciphertext, ArraySegment`1 additionalAuthenticatedData)
         at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status)
         at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(Byte[] protectedData, Boolean ignoreRevocationErrors, Boolean& requiresMigration, Boolean& wasRevoked)
         at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData)

Root causes

There are usually two typical causes for the above exception:

  • Private key is not persisted thus if the value was encrypted with a key from one instance, it cannot be decrypted using the current key.
  • Application name is not set.

Since we are persisting the keys to a database, the latter is the root cause.

Fix the problem

To fix the problem, we just need to call SetApplicationName function to ensure the application name is not consistent among different runs. If it is not specified, a random application name will be used and even if the key is the same the payload cannot be decrypted. 

services.AddDataProtection()
                .PersistKeysToDbContext<ApplicationDbContext>()
                .SetApplicationName("YourAppName")
                .SetDefaultKeyLifetime(TimeSpan.FromDays(180));

References

Configure ASP.NET Core Data Protection | Microsoft Docs

More from Kontext
comment Comments
No comments yet.

Please log in or register to comment.

account_circle Log in person_add Register

Log in with external accounts