Есть ли способ расшифровать файл jpg или png в Python, который зашифрован CSE KMS с использованием JAVA — AmazonS3EncryptionClient и хранится в S3? Похоже, что клиенты шифрования boto3 и aws поддерживают только зашифрованный текст, а не файл.
Я пробовал код ниже, но он терпит неудачу,
def get_decrypted_stream(s3_object):
region_name = 'us-east-1'
encryptedImageBytes = s3_object.get()['Body'].read()
print("Decoded file : {}".format(encryptedImageBytes))
client = boto3.client('kms', region_name=region_name)
response = client.decrypt( CiphertextBlob=encryptedImageBytes)
data = meta[u'Plaintext']
return io.BytesIO(data)
Ошибка:
Сбой на «client.decrypt(CiphertextBlob=encryptedImage)» с { «errorMessage»: «Произошла ошибка (413) при вызове операции расшифровки: длина содержимого HTTP превысила 200000 байт.», «errorType»: «ClientError», }
Использованная литература : https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.htmlhttps://github.com/aws/aws-шифрование-sdk-python/https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/python-example-code.htmlhttps://aws-шифрование-sdk-python.readthedocs.io/en/latest/






Согласно документации, которой вы поделились, Encrypt и Decrypt API ограничены максимальной полезной нагрузкой 4k: https://docs.aws.amazon.com/kms/latest/APIReference/API_Encrypt.html
При использовании ключей KMS для кодирования файлов философия заключается в создании симметричного ключа, кодировании полезной нагрузки с помощью симметричного ключа, кодировании симметричного ключа с помощью KMS encrypt API и сохранении зашифрованного симметричного ключа в конверте в качестве метаданных на S3. Например.
Вот пример кода для шифрования файла S3:
#
# Generate a Data Key (encoded with my Master Key in KMS)
#
key = kms.generate_data_key(KeyId=MASTER_KEY_ARN,KeySpec='AES_256')
keyPlain = key['Plaintext']
keyCipher = key['CiphertextBlob']
#
# Encode a file with the data key
#
print ("Initializing encryption engine")
iv = ''.join(chr(random.randint(0, 0xFF)) for i in range(16))
chunksize = 64*1024
encryptor = AES.new(keyPlain, AES.MODE_CBC, iv)
print ("KMS Plain text key = %s " % base64.b64encode(keyPlain))
print ("KMS Encrypted key = %s " % base64.b64encode(keyCipher))
in_filename = os.path.join(DIRECTORY, FILENAME)
out_filename = in_filename + '.enc'
filesize = os.path.getsize(in_filename)
print ("Encrypting file")
with open(in_filename, 'rb') as infile:
with open(out_filename, 'wb') as outfile:
outfile.write(struct.pack('<Q', filesize))
outfile.write(iv)
chunk = infile.read(chunksize)
while len(chunk) != 0:
if len(chunk) % 16 != 0:
chunk += ' ' * (16 - len(chunk) % 16)
outfile.write(encryptor.encrypt(chunk))
chunk = infile.read(chunksize)
#
# Store encrypted file on S3
# Encrypted Key will be stored as meta data
#
print ("Storing encrypted file on S3")
metadata = {
"key" : base64.b64encode(keyCipher)
}
#client = boto3.client('s3', 'us-west-2')
s3 = session.client('s3')
transfer = S3Transfer(s3)
transfer.upload_file(out_filename, S3_BUCKET, out_filename, extra_args = {"Metadata" : metadata})
os.remove(out_filename)
и пример кода для расшифровки:
#
# Download Encrypted File and it's metadata
#
print ("Download file and meta data from S3")
transfer.download_file(S3_BUCKET, out_filename, out_filename)
#retrieve meta data
import boto3
s3 = boto3.resource('s3')
object = s3.Object(S3_BUCKET, out_filename)
#print object.metadata
keyCipher = base64.b64decode(object.metadata['key'])
#decrypt encrypted key
print ("Decrypt ciphered key")
key = kms.decrypt(CiphertextBlob=keyCipher)
keyPlain = key['Plaintext']
print ("KMS Plain text key = %s " % base64.b64encode(keyPlain))
print ("KMS Encrypted key = %s " % base64.b64encode(keyCipher))
#
# Decrypt the file
#
print("Decrypt the file")
in_filename = out_filename
out_filename = in_filename + '.jpg'
filesize = os.path.getsize(in_filename)
with open(in_filename, 'rb') as infile:
origsize = struct.unpack('<Q', infile.read(struct.calcsize('Q')))[0]
iv = infile.read(16)
decryptor = AES.new(keyPlain, AES.MODE_CBC, iv)
with open(out_filename, 'wb') as outfile:
chunk = infile.read(chunksize)
while len(chunk) != 0:
outfile.write(decryptor.decrypt(chunk))
chunk = infile.read(chunksize)
outfile.truncate(origsize)