#!/usr/bin/env python # Decrypts the Tom-Skype 5.5.x, 5.8.x, 5.9.x, and 5.10.x era keyfiles and # outputs them in UTF-8 # Jeffrey Knockel jeffk cs unm edu # Usage: python decrypt.py < keyfile > plainfile import binascii import struct import sys from Crypto.Cipher import DES as Cipher KEY = b'\x7a\xdd\xe7\xdc\x23\x25\x53\x75' def decrypt(key, hexcrypt): crypt = binascii.a2b_hex(hexcrypt.encode('ascii')) cipher = Cipher.new(key, Cipher.MODE_ECB) return cipher.decrypt(crypt).split(b'\0')[0] # This is the algorithm for Tom-Skype 3.6.x - 4.2.x era keyfiles that is # sometimes mistakenly used by the Tom-Skype folks for encrypting new words in # these keyfiles. Although we can decrypt these words, newer versions of # Tom-Skype can't, and so words encrypted with this algorithm won't actually # trigger censorship or surveillance. def decrypt_alt(hexcrypt): crypt = [int(hexcrypt[i:i + 2], 16) for i in range(0, len(hexcrypt), 2)] return b''.join(struct.pack('B', ((b ^ 0x68) - a) % 255) for a, b in zip(crypt, crypt[1:])) def main(): if hasattr(sys.stdout, 'buffer'): sys.stdout = sys.stdout.buffer for lineno, line in enumerate(sys.stdin): stripped = line.strip('\0\t\n\x0b\x0c\r ') if stripped: try: try: plain = decrypt(KEY, stripped).decode('gbk').encode('utf-8') except Exception: plain = decrypt_alt(stripped).decode('gbk').encode('utf-8') except Exception: sys.stderr.write('Error decrypting line %d\n' % (lineno + 1)) else: sys.stdout.write(plain + b'\n') if __name__ == '__main__': main()