Python — расшифровать файл образа S3, зашифрованный с помощью CSE KMS

Есть ли способ расшифровать файл 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/

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
1 911
1

Ответы 1

Согласно документации, которой вы поделились, 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)

Другие вопросы по теме