Today, I had the need to replicate an encrypted query string token to inter-operate with a third-party commercial application. I was able to determine the library, symmetrical algorithm and secret key being used to create the token. Turns out, it was an ASP.net web application using the Chilkat .NET library to do the encryption and decryption. Specifically, it was the Chilkat AES (aka Rijndael) methods being used.
It took me awhile to properly replicate. Luckily, the Chilkat team had made a blog post on inter-library compatibility: https://www.chilkatsoft.com/p/p_123.asp.
From that, I was able to work out the appropriate settings, and put together these wrapper methods.
# PyCrypto import from Crypto.Cipher import AES def chilkat_aes_encrypt(key, bytes, hex=False, iv=None, mode=None): """ Method to emulate the default settings of Chilkat AES decryption using PyCrypto. See: https://www.chilkatsoft.com/p/p_123.asp """ if len(key) < 16: key += '\0' * ( 16 - len(key) ) pass if iv is None: iv = chr(0) * 16 pass if mode is None: mode = AES.MODE_CBC pass remainder = len(bytes) / 16 if remainder > 0: pad_len = ((( len(bytes) // 16 ) + 1) * 16) - len(bytes) bytes += chr(pad_len) * pad_len pass cipher = AES.new(key, mode, iv) crypt = cipher.encrypt(bytes) if hex: crypt = binascii.hexlify(crypt).upper() pass return crypt def chilkat_aes_decrypt(key, bytes, hex=False, iv=None, mode=None): """ Method to emulate the default settings of Chilkat AES decryption using PyCrypto. See: https://www.chilkatsoft.com/p/p_123.asp """ if hex: bytes = binascii.unhexlify(bytes) pass if len(key) < 16: key += '\0' * ( 16 - len(key) ) pass if iv is None: iv = chr(0) * 16 pass if mode is None: mode = AES.MODE_CBC pass cipher = AES.new(key, mode, iv) plain = cipher.decrypt(bytes) last = ord( plain[-1] ) if last < 16 and len(plain) > last: indexed = ord( plain[ -1 * last ] ) if last == indexed: plain = plain[: -1 * last] pass pass return plain