Ejemplo n.º 1
0
    def decrypt(self, cipher_line):
        if not util.is_encrypted(cipher_line):
            raise KarnError('"%s" is not encrypted!' % cipher_line)
            
        # convert from base 32 to bytes literal
        cipherbytes = bytearray.fromhex(unicode(util.inttohex(int(cipher_line.strip(), 32))))

        output = bytearray()
        # start at byte 1 because byte 0 is the guard byte
        for i in xrange(1, len(cipherbytes), BLOCK_SIZE):
            cipher = cipherbytes[i:i+BLOCK_SIZE]
            
            # + is the concatenation operator in python
            # ^ is the xor operator
            leftmd = bytearray(hashlib.sha1(str(util.right(cipher)) + str(self.rightkey)).digest())
            leftcipher = util.left(cipher)
            plaintext = bytearray(leftmd[i] ^ leftcipher[i] for i in xrange(len(leftmd)))
            rightmd = bytearray(hashlib.sha1(str(plaintext) + str(self.leftkey)).digest())
            rightcipher = util.right(cipher)
            plaintext.extend(bytearray(rightmd[i] ^ rightcipher[i] for i in xrange(len(rightmd))))

            # break if we decrypted a null byte
            output.extend(plaintext.partition('\x00')[0])
            if '\x00' in plaintext:
                break

        # we are expecting an ascii string, so print debug info 
        # if any decrypted character is out of ascii range
        if any(i > 127 for i in output):
            print 'couldn\'t decrypt ciphertext: %s' % cipher_line
            print 'with key: %d' % self.key
            print 'output: %s' % output
            raise DecryptionError(cipher_line, self.key, output)

        return str(output)
Ejemplo n.º 2
0
    def __init__(self, key):
        self.key = key
        # need to convert integer to hex str before getting the byte array
        keybytes = bytearray.fromhex(unicode(util.inttohex(key)))

        # the monitor uses Java's BigInteger, which uses 2s complement.
        # that means that it will add on a 0 byte in front to preserve the
        # sign of the key, if the most significant bit of the key is set
        if keybytes[0] & (1 << 7):
            keybytes.insert(0,0)

        # even if the key ends up being an odd number of bytes, the monitor breaks it
        # into two equal halves, and the least significant byte gets discarded.
        # probably a bug in the monitor, but that's how it is
        halfkeylen = len(keybytes) // 2
        self.leftkey = keybytes[:halfkeylen]
        self.rightkey = keybytes[halfkeylen: 2*halfkeylen]