0

I don't have a problem with my code but I don't understand the different arguments you can use with pycrypto and AES encryption. so where I define my encryptor below, what is mode, and IV? the tutorial I found this on didn't really help me understand it. I have it working properly but I want to understand that the arguments are.

so Question #1: What are the arguments associated with defining a encryptor with pycrpto?

Question #2 is this an appropriate salting method for the encryption. I'm using a very long randomized ascii string, then converting it to a 256bit sha then using that to do AES encryption on the information, then I base64 encode and insert into the database.

def pad(string):
   return string + ((16-len(string) % 16) * '{' )

password = hashlib.sha256("").digest()  
IV = 16 * '\x00'
mode = AES.MODE_CBC
encryptor = AES.new(password, mode, IV=IV)

encrypted_customer_name = encryptor.encrypt(pad(customer_name))
encoded_ecryption_name = base64.b64encode(encrypted_customer_name)  

customer_name = base64.b64decode(customer_name)
decryptor = AES.new(password, mode, IV=IV)
customer_name = decryptor.decrypt(customer_name)
lenofdec = customer_name.count('{')
customer_name = customer_name[:len(customer_name)-lenofdec]

My code isn't in that order but I didn't include all of the code just the relevant parts.

jww
  • 83,594
  • 69
  • 338
  • 732
Grant Zukel
  • 1,033
  • 17
  • 43
  • Possible answer to Question #1: http://stackoverflow.com/questions/1220751/how-to-choose-an-aes-encryption-mode-cbc-ecb-ctr-ocb-cfb. Not sure I understand what salting you are talking about in Question #2... – Armin Rigo Oct 06 '14 at 21:37
  • 1
    I guess that you should first learn cryptography, and *then* try to understand how to apply it. Salts should be random, IV's should be randomized, padding should not be performed with a printable character, salts don't generate passwords and passwords are not keys. On the positive side, you are not using ECB mode of operation and you are applying base 64 at the right time. – Maarten Bodewes Oct 06 '14 at 21:40

1 Answers1

-1

Ok I'm going to do my best here to answer these questions!

Q1:

Ok it looks like the signature is

new(key, *args, **kwargs)

The first argument key is pretty self explanatory, but after that you notice that it can take a number of keyword arguments.

It seems that it can take:

  1. mode: The cypher mode (these are as follows. Look on wikipedia for definitions)

    MODE_ECB = 1 Electronic Code Book (ECB). See blockalgo.MODE_ECB. MODE_CBC = 2 Cipher-Block Chaining (CBC). See blockalgo.MODE_CBC. MODE_CFB = 3 Cipher FeedBack (CFB). See blockalgo.MODE_CFB. MODE_PGP = 4 This mode should not be used. MODE_OFB = 5 Output FeedBack (OFB). See blockalgo.MODE_OFB. MODE_CTR = 6 CounTer Mode (CTR). See blockalgo.MODE_CTR. MODE_OPENPGP = 7 OpenPGP Mode. See blockalgo.MODE_OPENPGP.

  2. IV: the salt (you seem to already understand this)

From here on out the options seem to be based on the specific mode you are using

  1. counter: A function that returns the next block of data (not normally used). From the docs:

    (Only MODE_CTR). A stateful function that returns the next counter block, which is a byte string of block_size bytes

  2. segment_size is the size of the segment in CFB mode

The Pycrypto docs

Q2: Is this a good method for salting your encryption?

First what is the salt for? I find that this is a very common question that people ask, I mean we already have a password, why else would we need a key?

The answer makes a lot of sense when you talk about passwords. Lets say my password is banana, when we write this to a password file we would send it through a hash algorithm and get 5a814... (sha256).

Now next time someone tries to use the password banana they get the same hash. Any one with permissions to the file can then look and see that the passwords are the same. This is where the salt comes in. If I append a random salt before running through the hash algorithm then the hash will come out different every time, even if the passwords are the same. This makes your system WAY more secure.

Alright now for your code:

First, congrats you are calling the function correctly! But... Your code sets IV = 16 * '\x00' this is not a very good salt at all. I would recommend using os.urandom(16) to generate high quality entropy (uses system entropy) and place the output in your code. It is common practice to write the salt into the beginning of the the encrypted content.

This is tricky to say without knowing what you are attempting to do with code, but let me explain with an example:

# Get User password

MODE = AES.MODE_CBC

def encrypt(msg, password):
    salt = os.urandom(16)
    password = sha256(password)
    crypter = AES.new(password, mode=MODE, IV=salt)
    return "{}:{}".format(salt, crypter.encrypt(msg))

def decrypt(enc, password):
    salt, content = enc.split(':')
    password = sha256(password)
    crypter = AES.new(password, mode=MODE, IV=salt)
    return crypter.decrypt(content)

I hope this was helpful! Happy Coding!

kzorro
  • 1,642
  • 2
  • 10
  • 4
  • 2
    An IV is not the same as a salt, and to create a key from a password and salt you should use bcrypt or PBKDF2 (removed sarcasm). – Maarten Bodewes Oct 06 '14 at 23:55
  • well all I'm doing is encrypting customer names accross a database, not even encrypting or storing passwords. – Grant Zukel Oct 07 '14 at 15:53
  • OK, that *is* relatively low key. But I had to comment and downvote because this is just incorrect information. And beware; had you e.g. chosen CTR with a static IV then you would have instantly lost all confidentiality. Again, you need to know what you're doing. – Maarten Bodewes Oct 07 '14 at 21:10