Sorry... there was supposed to be a 2 as well... i was making a numbered list. These days my brain is not functioning as well as I would like given my health.
My utility class does in fact use PyCrypto. What I was saying is PyCrypto has to be compiled on the host it is being run on because it has C in it. It's not native Python. I wonder though, it may be possible to get our hands on the modified source that Google has compiled in the GAE platform. That version would be pure python without IDEA. Attached is the file. Keep in mind that it will require a secret key exactly 256 bits or 32 bytes long. My intent is to cache the Class to prevent overhead and file locking issues reading the secret file every time I need encryption. I understand that there is risk to having the key in memory, but reading a file for every crypt or decrypt is silly. There are far better ways for securing the secret key. This is just an example. Enjoy. On Monday, October 1, 2012 8:21:19 PM UTC-4, Massimo Di Pierro wrote: > > Not sure I understand. Does your library uses PyCrypto or not? What do you > mean "due to 1"? > Anyway, I would like to see it. > > Massimo > > On Monday, 1 October 2012 17:15:51 UTC-5, Dave wrote: >> >> I wanted to post to the group that I have created a utility class for >> performing encryption and decryption using the PyCrypto library. It really >> can't be baked in to web2py due to 1, export restrictions, but also the >> underlying PyCrypto library is not pure python. There is some optimized C >> in the library. >> >> If anybody is interested, I can clean up the code, remove some of my more >> "trade secret" stuff and share it. If you are hosting on GAE, you may use >> PyCrpyto, but there are caveats. PGP and IDEA crpyt modules are not there >> due to licensing. Furthermore PKI operations are re-written by Google in >> pure python instead of optimized, faster C. This is due to their security >> policy. >> >> My utility class uses AES and the CFB mode. >> >> cheers >> > --
#!/usr/bin/env python # coding: utf8 """ Crpytography Functions authors: Dave Stoll <dave.st...@gmail.com> Jason Burosh <jbur...@gmail.com> """ from Crypto.Cipher import AES from Crypto import Random import base64, os class SjCrypt(object): BLOCK_SIZE = 16 MODE = AES.MODE_CFB def __init__(self, request=None): """ Default constructor for use in web2py. Set up system-wide symmetric encryption key """ if request: filename = os.path.join(request.folder,'private','encryption.secret') if not os.path.exists(filename): key = Random.get_random_bytes(32) open(filename,'w').write(key) self.secret = open(filename,'r').read().strip() else: # this is only for testing. Random key... do NOT use this way self.secret = Random.get_random_bytes(32) def crypt(self, inmsg): """ encryption method. crypt(string message) Returns a base64 encoded encrypted text """ # first set up the initialization vector # this should be done for each encryption iv=Random.get_random_bytes(self.BLOCK_SIZE) # now get a cipher object. # very important to do this each time you call crypt or decrypt c = AES.new(self.secret, self.MODE, iv) #encrypt the incoming message msg = c.encrypt(inmsg) #prepend the IV to the msg encrypted_bytes=iv+msg #return the base64 encoded string return base64.urlsafe_b64encode(encrypted_bytes) def decrypt(self, inmsg): """ decryption method. decrypt(string message) Takes a base64.urlsafe_b64encoded string as the only argument return the decrypted string """ # first we must decode the incoming message encrypted_bytes = base64.urlsafe_b64decode(inmsg) # next split the incoming message to obtain iv and data # the IV is the first BLOCK_SIZE bytes iv, msg = (encrypted_bytes[:self.BLOCK_SIZE], encrypted_bytes[self.BLOCK_SIZE:]) # now get a cipher object. # very important to do this each time you call crypt or decrypt c = AES.new(self.secret, self.MODE, iv) # decrypt the message and return it all together return c.decrypt(msg) def test(): """ this will test the class """ print 'Testing cryptography' msg = 'the british are coming' c = SjCrypt() print "msg before encryption: " + msg crypted = c.crypt(msg) print "encrypted message: " + crypted decrypted = c.decrypt(crypted) print "decrypted message: " + decrypted assert(msg == decrypted), "Decrypted message does not match original." print "Test successful!" if __name__ == "__main__": test()