AWS.Cryptography.EncryptionSDK.AwsEncryptionSdkException: Failed to build header body

114 Views Asked by At

I'm trying to use the AWS Encryption SDK for .NET to encrypt and decrypt plain text using KMS. When encrypting a string I see the the error in the title. I'm not sure what I'm doing wrong as I'm basically following the example code provided by AWS save for specifying credentials such that the SDK can access the KMS key (if I don't sepcify credentials I get the follwoing error 'Amazon.Runtime.AmazonServiceException: Unable to get IAM security credentials from EC2 Instance Metadata Service.'). I've already checked that the AccessKeyId and SecretKey have full access to the KMS key that is being specified using _options.KmsKeyArn. The error message isn't helpful at all. The same error is thrown when I attempt to use SessionCredentials with a token that hasn't expired yet.

`

public class CryptographyService : ICryptographyService
{

    private readonly ESDK _cryptoClient;
    private readonly MaterialProviders _materialProviders;
    private readonly CryptographyOptions _options;
    private readonly IKeyring _keyRing;

    public CryptographyService(IOptions<CryptographyOptions> options)
    {
        _options = options.Value;

        var credentials = new BasicAWSCredentials(_options.AccessKey, _options.SecretKey);

        _cryptoClient = new ESDK(new AwsEncryptionSdkConfig());
        _materialProviders = new MaterialProviders(new MaterialProvidersConfig());

        var keyringInput = new CreateAwsKmsKeyringInput
        {
            KmsClient = new AmazonKeyManagementServiceClient(credentials, RegionEndpoint.GetBySystemName(_options.RegionEndpoint)),
            KmsKeyId = _options.KmsKeyArn
        };

        _keyRing = _materialProviders.CreateAwsKmsKeyring(keyringInput);

        var createCmmInput = new CreateRequiredEncryptionContextCMMInput
        {
            UnderlyingCMM = _materialProviders.CreateDefaultCryptographicMaterialsManager(new CreateDefaultCryptographicMaterialsManagerInput { Keyring = _keyRing }),
            RequiredEncryptionContextKeys = new List<string>(_options.GetEncryptionContext().Keys)
        };

        _ = _materialProviders.CreateRequiredEncryptionContextCMM(createCmmInput);
    }

    public async ValueTask<string> EncryptPlainText(string plainText)
    {
        EncryptOutput encryptOutput;
        await using (var stream = MemoryStreamFromString(plainText))
        {
            var encryptInput = new EncryptInput()
            {
                Plaintext = stream,
                Keyring = _keyRing,
                EncryptionContext = _options.GetEncryptionContext()
            };
            encryptOutput = _cryptoClient.Encrypt(encryptInput);
        }
        return StringFromMemoryStream(encryptOutput.Ciphertext);
    }

    private static MemoryStream MemoryStreamFromString(string s) => new(Encoding.ASCII.GetBytes(s));
}`

I tried using session credentials with a valid token, specifying an encryption algorithm, not using an encryption context, not speciyfing CMM. All of this leads to the same error message. Not specifying credentials leads to an error message 'Amazon.Runtime.AmazonServiceException: Unable to get IAM security credentials from EC2 Instance Metadata Service.'

0

There are 0 best solutions below