AWS Encryption SDK for .NET加密时报错Failed to build header body求助
解决AWS Encryption SDK for .NET "Failed to build header body" 错误
问题点及对应修复方案
1. 未使用的自定义CMM引发流程异常
你的代码中创建了RequiredEncryptionContextCMM但未将其关联到加密客户端或请求中,这会干扰SDK内部的材料管理逻辑。如果不需要强制校验加密上下文,直接移除这部分冗余代码;如果需要使用该CMM,必须将其设置为客户端默认CMM或在加密请求中指定。
修复示例(移除冗余CMM代码):
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); // 移除未使用的RequiredEncryptionContextCMM创建代码 }
2. 字符串转流的编码错误
使用Encoding.ASCII转换包含非ASCII字符的明文时,会导致数据损坏,进而引发SDK头部构建失败。建议统一使用Encoding.UTF8处理字符串与字节流的转换:
修复编码逻辑:
private static MemoryStream MemoryStreamFromString(string s) => new(Encoding.UTF8.GetBytes(s)); // 解密时也要对应使用UTF8解码 private static string StringFromMemoryStream(MemoryStream stream) { stream.Position = 0; using var reader = new StreamReader(stream, Encoding.UTF8); return reader.ReadToEnd(); }
3. 加密上下文存在非法键值
如果加密上下文包含空键或空值,会破坏SDK的头部构建规则。添加校验过滤非法键值:
添加加密上下文校验:
var encryptionContext = _options.GetEncryptionContext() .Where(kv => !string.IsNullOrEmpty(kv.Key) && !string.IsNullOrEmpty(kv.Value)) .ToDictionary(kv => kv.Key, kv => kv.Value); var encryptInput = new EncryptInput() { Plaintext = stream, Keyring = _keyRing, EncryptionContext = encryptionContext };
4. KMS权限与配置二次确认
确保IAM凭证拥有kms:GenerateDataKey和kms:Encrypt权限,同时验证KMS客户端的区域配置与密钥所在区域完全匹配。
完整修复后的示例代码
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); var kmsClient = new AmazonKeyManagementServiceClient(credentials, RegionEndpoint.GetBySystemName(_options.RegionEndpoint)); _cryptoClient = new ESDK(new AwsEncryptionSdkConfig()); _materialProviders = new MaterialProviders(new MaterialProvidersConfig()); var keyringInput = new CreateAwsKmsKeyringInput { KmsClient = kmsClient, KmsKeyId = _options.KmsKeyArn }; _keyRing = _materialProviders.CreateAwsKmsKeyring(keyringInput); } public async ValueTask<string> EncryptPlainText(string plainText) { await using var stream = MemoryStreamFromString(plainText); var encryptionContext = _options.GetEncryptionContext() .Where(kv => !string.IsNullOrEmpty(kv.Key) && !string.IsNullOrEmpty(kv.Value)) .ToDictionary(kv => kv.Key, kv => kv.Value); var encryptInput = new EncryptInput { Plaintext = stream, Keyring = _keyRing, EncryptionContext = encryptionContext }; var encryptOutput = _cryptoClient.Encrypt(encryptInput); return StringFromMemoryStream(encryptOutput.Ciphertext); } private static MemoryStream MemoryStreamFromString(string s) => new(Encoding.UTF8.GetBytes(s)); private static string StringFromMemoryStream(MemoryStream stream) { stream.Position = 0; using var reader = new StreamReader(stream, Encoding.UTF8); return reader.ReadToEnd(); } }
内容的提问来源于stack exchange,提问作者dirk345
相关产品推荐
相关产品推荐

