0

i try to write a code , whom encrypt my data , then i try to execute me code i get an error:

import base64
import boto3
from Crypto.Cipher import AES

PAD = lambda s: s + (32 - len(s) % 32) * ' '


def get_arn(aws_data):
    return 'arn:aws:kms:{region}:{account_number}:key/{key_id}'.format(**aws_data)


def encrypt_data(aws_data, plaintext_message):
    kms_client = boto3.client(
        'kms',
        region_name=aws_data['region'])

    data_key = kms_client.generate_data_key(
        KeyId=aws_data['key_id'],
        KeySpec='AES_256')

    cipher_text_blob = data_key.get('CiphertextBlob')
    plaintext_key = data_key.get('Plaintext')

    # Note, does not use IV or specify mode... for demo purposes only.
    cypher = AES.new(plaintext_key, AES.MODE_EAX)
    encrypted_data = base64.b64encode(cypher.encrypt(PAD(plaintext_message)))

    # Need to preserve both of these data elements
    return encrypted_data, cipher_text_blob



def main():
    # Add your account number / region / KMS Key ID here.
    aws_data = {
        'region': 'eu-west-1',
        'account_number': '70117777xxxx',
        'key_id': 'xxxxxxx-83ac-4b5e-93d4-xxxxxxxx',
    }

    # And your super secret message to envelope encrypt...
    plaintext = b'Hello, World!'

    # Store encrypted_data & cipher_text_blob in your persistent storage. You will need them both later.
    encrypted_data, cipher_text_blob = encrypt_data(aws_data, plaintext)
    print(encrypted_data)


if __name__ == '__main__':
    main()

this is an error:

PAD = lambda s: s + (32 - len(s) % 32) * ' ' TypeError: can't concat str to bytes maybe whom know where is a problem ? please suggest

Андрей Ка
  • 756
  • 4
  • 14
  • 33

1 Answers1

1

Your function PAD is intended to work with a string input and you call it with a bytes input (b'Hello, World!' in your example).

PAD('Hello, World!') (without the leading b) works. One solution would be to pad the plaintext as a stringand convert it to bytesafterwards, e.g.:

plaintext = PAD('Hello, world!') plaintext_bytes = plaintext.encode('utf-8')

See this StackOverflow question for how to convert a stringto bytes.

pills
  • 656
  • 1
  • 5
  • 10
  • Oh , it works !! thanks , maybe you know which mode i need to use for encrypt this string ??? cypher = AES.new(plaintext_key, AES.MODE_EAX) then i use this , i get : TypeError: Only byte strings can be passed to C code , i try to use many aes.mode but nothing .. :( – Андрей Ка Sep 05 '17 at 09:09
  • Happy it works, in that case you can accept my solution ;) Regarding your second question, you probably have the reverse problem: you're passing a `string` when the AES function is expecting `bytes`. Try calling the AES function with `plaintext_key.encode('utf-8')` to see if this fixes the issue. – pills Sep 05 '17 at 09:20
  • Maybe you know how? – Андрей Ка Sep 05 '17 at 09:28
  • Check my previous comment; your error is most probably not linked to the mode you use but to how you call the AES methods (you should use `bytes`instead of `string`). Concerning which mode to use, I am not an expert and can only recommend that you google how to use the different AES modes (crypto is tricky to get right). – pills Sep 05 '17 at 09:38