Пример #1
0
    def isForHash(self, nthash):
        plaintext  = self.getPlaintext()
        c1, c2, c3 = self.getCiphertext()
        k1, k2, k3 = self._getKeysFromHash(nthash)

        return des.des_encrypt_block(k1, plaintext) == c1 and \
               des.des_encrypt_block(k2, plaintext) == c2 and \
               des.des_encrypt_block(k3, plaintext) == c3
Пример #2
0
    def isForHash(self, nthash):
        plaintext = self.getPlaintext()
        c1, c2, c3 = self.getCiphertext()
        k1, k2, k3 = self._getKeysFromHash(nthash)

        return des.des_encrypt_block(k1, plaintext) == c1 and \
               des.des_encrypt_block(k2, plaintext) == c2 and \
               des.des_encrypt_block(k3, plaintext) == c3
Пример #3
0
    def test_03_encrypt_bytes(self):
        "test des_encrypt_block()"
        from passlib.utils.des import (des_encrypt_block, shrink_des_key,
                                       _pack64, _unpack64)

        # run through test vectors
        for key, plaintext, correct in self.des_test_vectors:
            # convert to bytes
            key = _pack64(key)
            plaintext = _pack64(plaintext)
            correct = _pack64(correct)

            # test 64-bit key
            result = des_encrypt_block(key, plaintext)
            self.assertEqual(result, correct,
                             "key=%r plaintext=%r:" % (key, plaintext))

            # test 56-bit version
            key2 = shrink_des_key(key)
            result = des_encrypt_block(key2, plaintext)
            self.assertEqual(
                result, correct,
                "key=%r shrink(key)=%r plaintext=%r:" % (key, key2, plaintext))

            # test with random parity bits
            for _ in range(20):
                key3 = _pack64(self._random_parity(_unpack64(key)))
                result = des_encrypt_block(key3, plaintext)
                self.assertEqual(
                    result, correct, "key=%r rndparity(key)=%r plaintext=%r:" %
                    (key, key3, plaintext))

        # check invalid keys
        stub = b('\x00') * 8
        self.assertRaises(TypeError, des_encrypt_block, 0, stub)
        self.assertRaises(ValueError, des_encrypt_block, b('\x00') * 6, stub)

        # check invalid input
        self.assertRaises(TypeError, des_encrypt_block, stub, 0)
        self.assertRaises(ValueError, des_encrypt_block, stub, b('\x00') * 7)

        # check invalid salts
        self.assertRaises(ValueError, des_encrypt_block, stub, stub, salt=-1)
        self.assertRaises(ValueError,
                          des_encrypt_block,
                          stub,
                          stub,
                          salt=1 << 24)

        # check invalid rounds
        self.assertRaises(ValueError,
                          des_encrypt_block,
                          stub,
                          stub,
                          0,
                          rounds=0)
Пример #4
0
 def _gen_challenge_response(self, challenge_hash, nt_hash):
     _nt_hash = b''.join((nt_hash, b'\x00' * 5))
     challenge_response = b''
     key = des.expand_des_key(_nt_hash[:7])
     challenge_response += des.des_encrypt_block(key, challenge_hash)
     key = des.expand_des_key(_nt_hash[7:14])
     challenge_response += des.des_encrypt_block(key, challenge_hash)
     key = des.expand_des_key(_nt_hash[14:])
     challenge_response += des.des_encrypt_block(key, challenge_hash)
     return challenge_response
Пример #5
0
 def _gen_challenge_response(self, challenge_hash, nt_hash):
     _nt_hash = b''.join((nt_hash, b'\x00' * 5))
     challenge_response = b''
     key = des.expand_des_key(_nt_hash[:7])
     challenge_response += des.des_encrypt_block(key, challenge_hash)
     key = des.expand_des_key(_nt_hash[7:14])
     challenge_response += des.des_encrypt_block(key, challenge_hash)
     key = des.expand_des_key(_nt_hash[14:])
     challenge_response += des.des_encrypt_block(key, challenge_hash)
     return challenge_response
Пример #6
0
def raw_lmhash(secret, encoding="ascii", hex=False):
    "encode password using des-based LMHASH algorithm; returns string of raw bytes, or unicode hex"
    # NOTE: various references say LMHASH uses the OEM codepage of the host
    #      for it's encoding. until a clear reference is found,
    #      as well as a path for getting the encoding,
    #      letting this default to "ascii" to prevent incorrect hashes
    #      from being made w/o user explicitly choosing an encoding.
    if isinstance(secret, unicode):
        secret = secret.encode(encoding)
    ns = secret.upper()[:14] + b("\x00") * (14 - len(secret))
    out = des_encrypt_block(ns[:7], LM_MAGIC) + des_encrypt_block(ns[7:], LM_MAGIC)
    return hexlify(out).decode("ascii") if hex else out
Пример #7
0
def raw_lmhash(secret, encoding="ascii", hex=False):
    """encode password using des-based LMHASH algorithm; returns string of raw bytes, or unicode hex"""
    # NOTE: various references say LMHASH uses the OEM codepage of the host
    #       for its encoding. until a clear reference is found,
    #       as well as a path for getting the encoding,
    #       letting this default to "ascii" to prevent incorrect hashes
    #       from being made w/o user explicitly choosing an encoding.
    if isinstance(secret, unicode):
        secret = secret.encode(encoding)
    ns = secret.upper()[:14] + b"\x00" * (14 - len(secret))
    out = des_encrypt_block(ns[:7], LM_MAGIC) + des_encrypt_block(
        ns[7:], LM_MAGIC)
    return hexlify(out).decode("ascii") if hex else out
Пример #8
0
def checkKey(plaintext, ciphertext, b1, b2):
    keyCandidateBytes = chr(b1) + chr(b2) + (chr(0x00) * 5)
    keyCandidate      = des.expand_des_key(keyCandidateBytes)
    result            = des.des_encrypt_block(keyCandidate, plaintext)

    if result == ciphertext:
        return keyCandidateBytes
Пример #9
0
    def test_des_encrypt_block(self):
        for k,p,c in self.test_des_vectors:
            k = unhexlify(k)
            p = unhexlify(p)
            c = unhexlify(c)
            result = des.des_encrypt_block(k,p)
            self.assertEqual(result, c, "key=%r p=%r:" % (k,p))

        #test 7 byte key
        #FIXME: use a better key
        k,p,c = b('00000000000000'), b('FFFFFFFFFFFFFFFF'), b('355550B2150E2451')
        k = unhexlify(k)
        p = unhexlify(p)
        c = unhexlify(c)
        result = des.des_encrypt_block(k,p)
        self.assertEqual(result, c, "key=%r p=%r:" % (k,p))
Пример #10
0
def checkKey(plaintext, ciphertext, b1, b2):
    keyCandidateBytes = chr(b1) + chr(b2) + (chr(0x00) * 5)
    keyCandidate = des.expand_des_key(keyCandidateBytes)
    result = des.des_encrypt_block(keyCandidate, plaintext)

    if result == ciphertext:
        return keyCandidateBytes
Пример #11
0
    def test_parsing(self):
        capture    = open("tests/pptp.cap")
        reader     = ChapPacketReader(capture)
        handshakes = MultiChapStateManager()

        for packet in reader:
            handshakes.addHandshakePacket(packet)

        complete = handshakes.getCompletedHandshakes()

        assert len(complete) == 1

        for server in complete:
            for client in complete[server]:
                c1, c2, c3 = complete[server][client].getCiphertext()
                plaintext  = complete[server][client].getPlaintext()
                username   = complete[server][client].getUserName()

                assert username == "moxie"

                hash = nthash.raw_nthash('bPCFyF2uL1p5Lg5yrKmqmY')

                print "NT Hash: %s" % binascii.hexlify(hash)

                key1 = hash[0:7]
                key1 = des.expand_des_key(key1)

                key2 = hash[7:14]
                key2 = des.expand_des_key(key2)

                key3 = hash[14:16]
                key3 += (chr(0x00) * 5)
                key3 = des.expand_des_key(key3)

                result1 = des.des_encrypt_block(key1, plaintext)
                result2 = des.des_encrypt_block(key2, plaintext)
                result3 = des.des_encrypt_block(key3, plaintext)

                print "DES Encryption 1: %s" % binascii.hexlify(result1)
                print "C1: %s" % binascii.hexlify(c1)
                print "C2: %s" % binascii.hexlify(c2)
                print "C3: %s" % binascii.hexlify(c3)

                assert result1 == c1
                assert result2 == c2
                assert result3 == c3
Пример #12
0
    def test_des_encrypt_block(self):
        for k, p, c in self.test_des_vectors:
            k = unhexlify(k)
            p = unhexlify(p)
            c = unhexlify(c)
            result = des.des_encrypt_block(k, p)
            self.assertEqual(result, c, "key=%r p=%r:" % (k, p))

        #test 7 byte key
        #FIXME: use a better key
        k, p, c = b('00000000000000'), b('FFFFFFFFFFFFFFFF'), b(
            '355550B2150E2451')
        k = unhexlify(k)
        p = unhexlify(p)
        c = unhexlify(c)
        result = des.des_encrypt_block(k, p)
        self.assertEqual(result, c, "key=%r p=%r:" % (k, p))
Пример #13
0
    def test_03_encrypt_bytes(self):
        """test des_encrypt_block()"""
        from passlib.utils.des import (des_encrypt_block, shrink_des_key,
                                       _pack64, _unpack64)

        # run through test vectors
        for key, plaintext, correct in self.des_test_vectors:
            # convert to bytes
            key = _pack64(key)
            plaintext = _pack64(plaintext)
            correct = _pack64(correct)

            # test 64-bit key
            result = des_encrypt_block(key, plaintext)
            self.assertEqual(result, correct, "key=%r plaintext=%r:" %
                                              (key, plaintext))

            # test 56-bit version
            key2 = shrink_des_key(key)
            result = des_encrypt_block(key2, plaintext)
            self.assertEqual(result, correct, "key=%r shrink(key)=%r plaintext=%r:" %
                                              (key, key2, plaintext))

            # test with random parity bits
            for _ in range(20):
                key3 = _pack64(self._random_parity(_unpack64(key)))
                result = des_encrypt_block(key3, plaintext)
                self.assertEqual(result, correct, "key=%r rndparity(key)=%r plaintext=%r:" %
                                                  (key, key3, plaintext))

        # check invalid keys
        stub = b('\x00') * 8
        self.assertRaises(TypeError, des_encrypt_block, 0, stub)
        self.assertRaises(ValueError, des_encrypt_block, b('\x00')*6, stub)

        # check invalid input
        self.assertRaises(TypeError, des_encrypt_block, stub, 0)
        self.assertRaises(ValueError, des_encrypt_block, stub, b('\x00')*7)

        # check invalid salts
        self.assertRaises(ValueError, des_encrypt_block, stub, stub, salt=-1)
        self.assertRaises(ValueError, des_encrypt_block, stub, stub, salt=1<<24)

        # check invalid rounds
        self.assertRaises(ValueError, des_encrypt_block, stub, stub, 0, rounds=0)
Пример #14
0
    def raw(cls, secret, encoding=None):
        """encode password using LANMAN hash algorithm.

        :type secret: unicode or utf-8 encoded bytes
        :arg secret: secret to hash
        :type encoding: str
        :arg encoding:
            optional encoding to use for unicode inputs.
            this defaults to ``cp437``, which is the
            common case for most situations.

        :returns: returns string of raw bytes
        """
        if not encoding:
            encoding = cls.default_encoding
        # some nice empircal data re: different encodings is at...
        # http://www.openwall.com/lists/john-dev/2011/08/01/2
        # http://www.freerainbowtables.com/phpBB3/viewtopic.php?t=387&p=12163
        from passlib.utils.des import des_encrypt_block
        MAGIC = cls._magic
        if isinstance(secret, unicode):
            # perform uppercasing while we're still unicode,
            # to give a better shot at getting non-ascii chars right.
            # (though some codepages do NOT upper-case the same as unicode).
            secret = secret.upper().encode(encoding)
        elif isinstance(secret, bytes):
            # FIXME: just trusting ascii upper will work?
            # and if not, how to do codepage specific case conversion?
            # we could decode first using <encoding>,
            # but *that* might not always be right.
            secret = secret.upper()
        else:
            raise TypeError("secret must be unicode or bytes")
        secret = right_pad_string(secret, 14)
        return des_encrypt_block(secret[0:7], MAGIC) + \
               des_encrypt_block(secret[7:14], MAGIC)
Пример #15
0
    def raw(cls, secret, encoding=None):
        """encode password using LANMAN hash algorithm.

        :type secret: unicode or utf-8 encoded bytes
        :arg secret: secret to hash
        :type encoding: str
        :arg encoding:
            optional encoding to use for unicode inputs.
            this defaults to ``cp437``, which is the
            common case for most situations.

        :returns: returns string of raw bytes
        """
        if not encoding:
            encoding = cls.default_encoding
        # some nice empircal data re: different encodings is at...
        # http://www.openwall.com/lists/john-dev/2011/08/01/2
        # http://www.freerainbowtables.com/phpBB3/viewtopic.php?t=387&p=12163
        from passlib.utils.des import des_encrypt_block
        MAGIC = cls._magic
        if isinstance(secret, unicode):
            # perform uppercasing while we're still unicode,
            # to give a better shot at getting non-ascii chars right.
            # (though some codepages do NOT upper-case the same as unicode).
            secret = secret.upper().encode(encoding)
        elif isinstance(secret, bytes):
            # FIXME: just trusting ascii upper will work?
            # and if not, how to do codepage specific case conversion?
            # we could decode first using <encoding>,
            # but *that* might not always be right.
            secret = secret.upper()
        else:
            raise TypeError("secret must be unicode or bytes")
        secret = right_pad_string(secret, 14)
        return des_encrypt_block(secret[0:7], MAGIC) + \
               des_encrypt_block(secret[7:14], MAGIC)
Пример #16
0
def des_cbc_encrypt(key, value, iv=b('\x00') * 8, pad=b('\x00')):
    """performs des-cbc encryption, returns only last block.

    this performs a specific DES-CBC encryption implementation
    as needed by the Oracle10 hash. it probably won't be useful for
    other purposes as-is.

    input value is null-padded to multiple of 8 bytes.

    :arg key: des key as bytes
    :arg value: value to encrypt, as bytes.
    :param iv: optional IV
    :param pad: optional pad byte

    :returns: last block of DES-CBC encryption of all ``value``'s byte blocks.
    """
    value += pad * (-len(value) % 8) #null pad to multiple of 8
    hash = iv #start things off
    for offset in xrange(0,len(value),8):
        chunk = xor_bytes(hash, value[offset:offset+8])
        hash = des_encrypt_block(key, chunk)
    return hash
Пример #17
0
def des_cbc_encrypt(key, value, iv=b('\x00') * 8, pad=b('\x00')):
    """performs des-cbc encryption, returns only last block.

    this performs a specific DES-CBC encryption implementation
    as needed by the Oracle10 hash. it probably won't be useful for
    other purposes as-is.

    input value is null-padded to multiple of 8 bytes.

    :arg key: des key as bytes
    :arg value: value to encrypt, as bytes.
    :param iv: optional IV
    :param pad: optional pad byte

    :returns: last block of DES-CBC encryption of all ``value``'s byte blocks.
    """
    value += pad * (-len(value) % 8) # null pad to multiple of 8
    hash = iv # start things off
    for offset in irange(0,len(value),8):
        chunk = xor_bytes(hash, value[offset:offset+8])
        hash = des_encrypt_block(key, chunk)
    return hash
Пример #18
0
 def test_des(self):
     result = des.des_encrypt_block('12345678', 'ABCDEFGH')
     assert binascii.hexlify(result) == "96de603eaed6256f"