gpt4 book ai didi

c# - .NET 中带有 KMS 的 AWS S3 客户端加密在最后一部分传输时发出 ProtocolViolationException

转载 作者:行者123 更新时间:2023-11-30 12:40:56 26 4
gpt4 key购买 nike

以下代码尝试使用多部分传输、客户端信封加密和 Amazon KMS 服务处理数据加密 key ,将 17MB 的测试文件复制到 S3 存储桶。多部分块大小为 5MB。

在传输最后一个(部分) block 时,如果 IsLastPart 标志设置为 true,调用 UploadPart 生成一个 System.Net.ProtocolViolationException 指示:要写入流的字节超过指定的 Content-Length 字节大小。

这表明 Content-Length html header 未更新以反射(reflect)加密引擎为正确对齐而添加到最后一个密码 block 的必要“填充字节”。结果,当添加这些最终字节时,它们超出了给定的 Content-Length 并生成了此错误。

如果 IsLastPart 设置(即 false),则操作成功,但下载和解密操作也失败。

注意:AWS .NET SDK 不提供 KmsAlgorithm 类。这个类来自另一个 Stack Overflow posting因为 AWS SDK 的 .NET 版本不提供 connector class在 KMS 和 S3 之间,以像 Java SDK 一样支持信封加密。

那么使用客户端加密和 KMS 托管 key 将分段上传发送到 S3 的正确方法是什么?

    static string bucketName = "*****************************";
static string keyName = "test.encrypted.bin";
static string uploadSourcePath = "c:\\temp\\test.bin";
static long partSize = 5 * 1024 * 1024;
static String uploadId = "";

static void Main(string[] args)
{
if (checkRequiredFields())
{
String cmkId = "************************************";

// Prepare our KMS client and kmsAlgorithm
using (AmazonKeyManagementServiceClient kmsClient = new AmazonKeyManagementServiceClient())
using (KMSAlgorithm kmsAlgo = new KMSAlgorithm(kmsClient, cmkId))
{
// Generate the encryption materials object with the algorithm object
EncryptionMaterials encryptionMaterials = new EncryptionMaterials(kmsAlgo);

// Now prepare an S3 crypto client
using (AmazonS3EncryptionClient cryptoClient = new AmazonS3EncryptionClient(encryptionMaterials))
{
// Initiate the multipart upload request specifying the bucket and key values
InitiateMultipartUploadResponse initResp = cryptoClient.InitiateMultipartUpload(
new InitiateMultipartUploadRequest()
{
BucketName = bucketName,
Key = keyName
});

uploadId = initResp.UploadId;

long fileLength = new FileInfo(uploadSourcePath).Length;
long contentLength = fileLength;
long bytesRemaining = fileLength;


List<PartETag> partETags = new List<PartETag>();
int partNumber = 0;

while (bytesRemaining > 0)
{
long transferSize = bytesRemaining > partSize ? partSize : bytesRemaining;
long partIndex = fileLength - bytesRemaining;

partNumber++;

UploadPartResponse resp =
cryptoClient.UploadPart(
new UploadPartRequest()
{
BucketName = bucketName,
Key = keyName,
FilePath = uploadSourcePath,
FilePosition = partIndex,
PartSize = transferSize,
PartNumber = partNumber,
UploadId = uploadId,
IsLastPart = transferSize < AwsS3FileSystemSample1.Program.partSize
});

partETags.Add( new PartETag( partNumber, resp.ETag ));

bytesRemaining -= transferSize;
}

// Now complete the transfer
CompleteMultipartUploadResponse compResp = cryptoClient.CompleteMultipartUpload(
new CompleteMultipartUploadRequest()
{
Key = keyName,
BucketName = bucketName,
UploadId = initResp.UploadId,
PartETags = partETags
});
}
}
}

Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}

如有任何错误,我们深表歉意。我们将不胜感激。

最佳答案

经过大量测试并在 AWS SDK for .NET 源代码的 git hub 上进行了一些代码探索后,神奇的 secret 是将 UploadPartRequestPartSize 成员设置为零(0) 将 IsLastPart 成员设置为 true 时。

究竟为什么这有效是一个有争议的问题。由于最后一部分的数据通常由加密引擎填充以满足密码 block 边界,因此实际的内容长度在加密完成之前是未知的。或许将 PartSize 设置为零允许底层代码将 Content-Length 设置为密文的填充长度,而不是 PartSize 中给出的值>。为什么当 IsLastPart 设置为 true 时这不会自动完成是一个谜。

无论如何,以下摘要可能有所帮助。使用客户端加密和分段上传时,在上传对象数据的最后一部分时,将 PartSize 成员设置为零 (0) 并将 IsLastPart 设置为 true。

此代码片段可能会有所帮助。

      while (bytesRemaining > 0)
{
long transferSize = bytesRemaining > partSize ? partSize : bytesRemaining;
long partIndex = fileLength - bytesRemaining;

bytesRemaining -= transferSize;
bool isLastPart = bytesRemaining == 0;

partNumber++;

UploadPartResponse resp =
cryptoClient.UploadPart(
new UploadPartRequest()
{
BucketName = bucketName,
Key = keyName,
FilePath = uploadSourcePath,
FilePosition = partIndex,
PartSize = isLastPart ? 0 : transferSize,
PartNumber = partNumber,
UploadId = uploadId,
IsLastPart = isLastPart
});

partETags.Add( new PartETag( partNumber, resp.ETag ));
}

我希望这对其他人有帮助。

关于c# - .NET 中带有 KMS 的 AWS S3 客户端加密在最后一部分传输时发出 ProtocolViolationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40024051/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com