在python中为boto3文件加密创建SSECustomerKey的正确方法是什么?

在python中为boto3文件加密创建SSECustomerKey的正确方法是什么?,python,encryption,amazon-s3,boto,boto3,Python,Encryption,Amazon S3,Boto,Boto3,我在django应用程序中使用boto3将媒体上传到S3。但我在使用“使用客户提供的加密密钥进行服务器端加密”加密服务器上的文件时遇到问题 我正在使用boto3的object.put()api上载文件并指定加密密钥。但是我得到了以下错误 “计算出的密钥MD5哈希值与指定的哈希值不匹配 提供。” 我不确定如何创建将在服务器端匹配的密钥的md5。这是我的密码 password = "32characterslongpassphraseneeded".encode('utf-8') encryptio

我在django应用程序中使用boto3将媒体上传到S3。但我在使用“使用客户提供的加密密钥进行服务器端加密”加密服务器上的文件时遇到问题

我正在使用boto3的object.put()api上载文件并指定加密密钥。但是我得到了以下错误

“计算出的密钥MD5哈希值与指定的哈希值不匹配 提供。”

我不确定如何创建将在服务器端匹配的密钥的md5。这是我的密码

password = "32characterslongpassphraseneeded".encode('utf-8')
encryption_key = hashlib.md5(password).hexdigest()
encryption_key_md5 = hashlib.md5(encryption_key.encode('utf-8')).hexdigest()
import boto3
s3 = boto3.resource('s3')
key = s3.Object(bucket_name, key_name)
kwargs = {
            'SSECustomerAlgorithm': 'AES256',
            'SSECustomerKey': encryption_key,
            'SSECustomerKeyMD5': encryption_key_md5,
            'ContentType': file_obj.content_type,
            'Body': file_obj,
        }

key.put(**kwargs)
我通过一个php客户端使用相同的S3API,它工作得很好

$name="somename"
$customerKey = md5($name);
                    $s3->putObject([
                        'Bucket' => S3_BUCKET,
                        'Key'    => "scope/{$name}",
                        'Body'   => fopen($tmp_file_path, 'rb'),
                        'ACL'    => S3_ACL,
                        'SSECustomerAlgorithm' => 'AES256',
                        'SSECustomerKey'       => $customerKey,
                        'SSECustomerKeyMD5'    => md5($customerKey ,true),
                    ]);

我在这里看到的唯一区别是php的md5方法可以接受第二个参数,如果为true,则返回16个字符长的摘要,而不是正常的32个字符长的摘要。现在我不知道如何使用hashlib.md5创建一个16个字符的摘要

正确的方法是使用
os.uradom

import os
secret_key = os.urandom(32) # The key needs to be 32 character long.
当boto3为您计算时,您不需要提供
SSECustomerKeyMD5

而且SSE-C在
键中也不能正常工作。put
,至于现在,我不知道是什么原因。必须这样做

s3 = boto3.client('s3')
s3.put_object(**kwargs)

SSE似乎也适用于
对象
。下面是一个例子

import boto3
from botocore.config import Config

s3 = boto3.resource('s3', 
                    region_name="us-east-1",
                    aws_access_key_id="key id",
                    aws_secret_access_key="access key",
                    config=Config(signature_version='s3v4')) 
s3.Object("bucket", "filename").put(Body="text",
                                    SSEKMSKeyId="some id",
                                    ServerSideEncryption='aws:kms')
要阅读它,请使用

s3.Object("bucket", "filename").get()['Body'].read()

如果不提供
SSECustomerKeyMD5
参数,会发生什么情况?Boto3应该为您计算它。如果我不提供它,那么我将收到400个错误请求错误。SSECustomerKey和MD5应该在base64中,因此不匹配