Forum Archive

objc_util and CommonCrypto

userista

I am trying to use objc_util to use some CommonCrypto methods but I can't seem to figure out how to load the CommonCrypto framework.

My goal is to decrypt something using native AES. And also to use the native pbkdf2 implementation.

Most python implementations of AES use compiled c code. I haven't found a "pure python" version that works on Pythonista.

Is this possible using the objc_util module?

JonB

I dint think you need to load it. just reference the functions

i.e

from obj_util import *

CCCryptorCreate = c.CCCryptorCreate
CCCryptorCreate.argtypes = [.......]
CCCryptorCreate.restype = ......

you might want to check out Cethrics work converting opengles, i think he used a method to use c like prototypes to autogenerate the ctypes wrappers.

userista

Does that mean I would have to write c like code to use this framework?

I found a library that wraps CommonCrypto to encrypt/decrypt using AES written in objc- I wanted to port it over to Pythonista...

https://github.com/rnapier/ios5ptl/blob/master/ch11/CryptPic/CryptPic/RNCryptManager.m

jadeblaquiere

AES is available out of the box, see example usage below. Though I would be interested to compare to native CommonCrypto as a benchmark...

import base64
import hashlib
from Crypto import Random
from Crypto.Cipher import AES

class AESCipher(object):

    def __init__(self, key): 
        self.bs = 32
        self.key = hashlib.sha256(key.encode()).digest()

    def encrypt(self, raw):
        raw = self._pad(raw)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return base64.b64encode(iv + cipher.encrypt(raw))

    def decrypt(self, enc):
        enc = base64.b64decode(enc)
        iv = enc[:AES.block_size]
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return self._unpad(cipher.decrypt(enc[AES.block_size:])).decode('utf-8')

    def _pad(self, s):
        return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs)

    @staticmethod
    def _unpad(s):
        return s[:-ord(s[len(s)-1:])]

if __name__ == '__main__':  # pragma: no cover
    aes = AESCipher('this is my key')
    plaintext = 'hello, I am very happy to meet you!'
    print 'plain  =', plaintext
    ciphertext = aes.encrypt(plaintext)
    print 'cipher =', ciphertext
    plaintwo = aes.decrypt(ciphertext)
    print 'plain2 =', plaintwo


userista

@jadeblaquiere said:

AES is available out of the box, see example usage below.

Thanks you so much! I had no idea the Crypto module was included - I didn't see any documentation for it.... (though I probably should've checked site-packages)