def ComputeResponsev2(NegFlg, ResponseKeyNT, ResponseKeyLM, ServerChallenge, ClientChallenge, Time=None, ServerName=None, av_pairs=None): if Time is None: Time = nttime.NtTime(nttime.datetime.now()) if ServerName is None: ServerName = "SERVER" ServerName = ServerName.encode("utf-16-le") TimeBuf = array.array("B") cur = core.Cursor(TimeBuf,0) cur.encode_uint64le(Time) Responseversion = "\x01" HiResponseversion = "\x01" ntlmv2_client_challenge = NTLMv2ClientChallenge() ntlmv2_client_challenge.time_stamp = Time ntlmv2_client_challenge.challenge_from_client = ClientChallenge if av_pairs is not None: ntlmv2_client_challenge.av_pairs = av_pairs temp = encode_frame(ntlmv2_client_challenge).tostring() NTProofStr = HMAC.new(ResponseKeyNT, ServerChallenge + temp, MD5).digest() NtChallengeResponse = NTProofStr + temp LmChallengeResponse = HMAC.new(ResponseKeyLM, ServerChallenge + ClientChallenge, MD5).digest() +\ ClientChallenge SessionBaseKey = HMAC.new(ResponseKeyNT, NTProofStr, MD5).digest() return NtChallengeResponse, LmChallengeResponse, SessionBaseKey
def runTest(self): key = b"0" * 16 data = b"\x00\x01\x02" # Data and key can be a bytearray (during initialization) key_ba = bytearray(key) data_ba = bytearray(data) h1 = HMAC.new(key, data) h2 = HMAC.new(key_ba, data_ba) key_ba[:1] = b'\xFF' data_ba[:1] = b'\xFF' self.assertEqual(h1.digest(), h2.digest()) # Data can be a bytearray (during operation) key_ba = bytearray(key) data_ba = bytearray(data) h1 = HMAC.new(key) h2 = HMAC.new(key) h1.update(data) h2.update(data_ba) data_ba[:1] = b'\xFF' self.assertEqual(h1.digest(), h2.digest())
def runTest(self): key = b"0" * 16 data = b"\x00\x01\x02" def get_mv_ro(data): return memoryview(data) def get_mv_rw(data): return memoryview(bytearray(data)) for get_mv in (get_mv_ro, get_mv_rw): # Data and key can be a memoryview (during initialization) key_mv = get_mv(key) data_mv = get_mv(data) h1 = HMAC.new(key, data) h2 = HMAC.new(key_mv, data_mv) if not data_mv.readonly: key_mv[:1] = b'\xFF' data_mv[:1] = b'\xFF' self.assertEqual(h1.digest(), h2.digest()) # Data can be a memoryview (during operation) data_mv = get_mv(data) h1 = HMAC.new(key) h2 = HMAC.new(key) h1.update(data) h2.update(data_mv) if not data_mv.readonly: data_mv[:1] = b'\xFF' self.assertEqual(h1.digest(), h2.digest())
def encrypt(cls, key, keyusage, plaintext, confounder): if confounder is None: confounder = get_random_bytes(8) ki = HMAC.new(key.contents, cls.usage_str(keyusage), MD5).digest() cksum = HMAC.new(ki, confounder + plaintext, MD5).digest() ke = HMAC.new(ki, cksum, MD5).digest() return cksum + ARC4.new(ke).encrypt(bytes(confounder + plaintext))
def GSS_GetMIC(self, sessionKey, data, sequenceNumber, direction = 'init'): GSS_GETMIC_HEADER = '\x60\x23\x06\x09\x2a\x86\x48\x86\xf7\x12\x01\x02\x02' token = self.MIC() # Let's pad the data pad = (4 - (len(data) % 4)) & 0x3 padStr = chr(pad) * pad data += padStr token['SGN_ALG'] = GSS_HMAC if direction == 'init': token['SND_SEQ'] = struct.pack('>L', sequenceNumber) + '\x00'*4 else: token['SND_SEQ'] = struct.pack('>L', sequenceNumber) + '\xff'*4 Ksign = HMAC.new(sessionKey.contents, 'signaturekey\0', MD5).digest() Sgn_Cksum = MD5.new( struct.pack('<L',15) + str(token)[:8] + data).digest() Sgn_Cksum = HMAC.new(Ksign, Sgn_Cksum, MD5).digest() token['SGN_CKSUM'] = Sgn_Cksum[:8] Kseq = HMAC.new(sessionKey.contents, struct.pack('<L',0), MD5).digest() Kseq = HMAC.new(Kseq, token['SGN_CKSUM'], MD5).digest() token['SND_SEQ'] = ARC4.new(Kseq).encrypt(token['SND_SEQ']) finalData = GSS_GETMIC_HEADER + token.getData() return finalData
def decrypt(self, key): if self['HashAlgo'] == ALGORITHMS.CALG_HMAC.value: hashModule = SHA1 else: hashModule = ALGORITHMS_DATA[self['HashAlgo']][1] prf = lambda p, s: HMAC.new(p, s, hashModule).digest() derivedBlob = self.deriveKey(key, self['Salt'], ALGORITHMS_DATA[self['CryptAlgo']][0] + ALGORITHMS_DATA[self['CryptAlgo']][3], count=self['MasterKeyIterationCount'], hashFunction=prf) cryptKey = derivedBlob[:ALGORITHMS_DATA[self['CryptAlgo']][0]] iv = derivedBlob[ALGORITHMS_DATA[self['CryptAlgo']][0]:][:ALGORITHMS_DATA[self['CryptAlgo']][3]] cipher = ALGORITHMS_DATA[self['CryptAlgo']][1].new(cryptKey, mode = ALGORITHMS_DATA[self['CryptAlgo']][2], iv = iv) cleartext = cipher.decrypt(self['data']) decryptedKey = cleartext[-64:] hmacSalt = cleartext[:16] hmac = cleartext[16:][:ALGORITHMS_DATA[self['HashAlgo']][0]] hmacKey = HMAC.new(key, hmacSalt, hashModule).digest() hmacCalculated = HMAC.new(hmacKey, decryptedKey, hashModule ).digest() if hmacCalculated[:ALGORITHMS_DATA[self['HashAlgo']][0]] == hmac: self.decryptedKey = decryptedKey return decryptedKey else: return None
def deriveKeysFromUser(self, sid, password): # Will generate two keys, one with SHA1 and another with MD4 key1 = HMAC.new(SHA1.new(password.encode('utf-16le')).digest(), (sid + '\0').encode('utf-16le'), SHA1).digest() key2 = HMAC.new(MD4.new(password.encode('utf-16le')).digest(), (sid + '\0').encode('utf-16le'), SHA1).digest() # For Protected users tmpKey = pbkdf2_hmac('sha256', MD4.new(password.encode('utf-16le')).digest(), sid.encode('utf-16le'), 10000) tmpKey2 = pbkdf2_hmac('sha256', tmpKey, sid.encode('utf-16le'), 1)[:16] key3 = HMAC.new(tmpKey2, (sid + '\0').encode('utf-16le'), SHA1).digest()[:20] return key1, key2, key3
def runTest(self): key = b("\x90\x91\x92\x93") * 4 payload = b("\x00") * 100 for hashname, hashmod in self.hashmods.items(): if hashmod is None: continue self.description = "Test HMAC in combination with " + hashname one = HMAC.new(key, payload, hashmod).digest() two = HMAC.new(key, payload, hashmod.new()).digest() self.assertEqual(one, two)
def verfiyMessageSignature(self, message, hex_mac, method=None, slot_id=DEFAULT_KEY): """ verify the hex mac is same for the message - the comparison is done in a constant time comparison :param message: the original message :param hex_mac: the to compared mac in hex :param method: the hash method - we use by default sha256 :param slot_id: which key should be used :return: boolean """ sign_key = None result = True if method is None: method = SHA256 try: sign_key = self.getSecret(slot_id) hmac = HMAC.new(sign_key, message, method) sign_mac = HMAC.new(sign_key, message, method).hexdigest() res = 0 # as we compare on hex, we have to multiply by 2 digest_size = hmac.digest_size * 2 for x, y in zip(hex_mac, sign_mac): res |= ord(x) ^ ord(y) if len(sign_mac) != digest_size: result = False if res: result = False except ValueError as err: log.error("Mac Comparison failed! %r", err) except Exception as exx: pass finally: if sign_key: zerome(sign_key) del sign_key return result
def signMessage(self, message, method=None, slot_id=DEFAULT_KEY): """ create the hex mac for the message - :param message: the original message :param method: the hash method - we use by default sha256 :param slot_id: which key should be used :return: hex mac """ sign_key = None if method is None: method = SHA256 try: sign_key = self.getSecret(slot_id) hex_mac = HMAC.new(sign_key, message, method).hexdigest() finally: if sign_key: zerome(sign_key) del sign_key return hex_mac
def aes_cbc_hmac_decrypt(key, iv, aad, ct, tag): """ Perform authenticated decryption with the combined AES-CBC and HMAC algorithm. :param key : Key; length MUST be 32, 48, or 64 octets :param iv : Initialization vector; length MUST be 16 octets :param aad: Additional authenticated data :param ct : Cipher text :param tag: Authentication tag :return: (plaintext, result) tuple, with plaintext as bytes and result as boolean """ ka, ke, seclen, dgst = get_keys_seclen_dgst(key, iv) # Verify A || IV || E || AL al = pack("!Q", 8*len(aad)) if isinstance(aad, str): aad = aad.encode("utf-8") mac_input = aad + iv + ct + al h = HMAC.new(ka, digestmod=dgst) h.update(mac_input) candidate = h.digest()[:seclen] # Decrypt if verified if candidate == tag: cipher = AES.new(ke, AES.MODE_CBC, iv) pt = pkcs5trim(cipher.decrypt(ct)) return pt else: raise VerificationFailure('AES-CBC HMAC')
def NTOWFv2(password, user, userdom): nt_passwd = password.encode("utf-16-le") nt_hash_passwd = MD4.new(nt_passwd).digest() nt_userdom = (user.upper() + userdom).encode("utf-16-le") return HMAC.new(nt_hash_passwd, nt_userdom, MD5).digest()
def deriveKey(self, sessionKey): def fixparity(deskey): from six import indexbytes, b temp = b'' for i in range(len(deskey)): t = (bin(indexbytes(deskey,i))[2:]).rjust(8,'0') if t[:7].count('1') %2 == 0: temp+= b(chr(int(t[:7]+'1',2))) else: temp+= b(chr(int(t[:7]+'0',2))) return temp if len(sessionKey) > ALGORITHMS_DATA[self['HashAlgo']][4]: derivedKey = HMAC.new(sessionKey, digestmod = ALGORITHMS_DATA[self['HashAlgo']][1]).digest() else: derivedKey = sessionKey if len(derivedKey) < ALGORITHMS_DATA[self['CryptAlgo']][0]: # Extend the key derivedKey += b'\x00'*ALGORITHMS_DATA[self['HashAlgo']][4] ipad = bytearray([ i ^ 0x36 for i in bytearray(derivedKey)][:ALGORITHMS_DATA[self['HashAlgo']][4]]) opad = bytearray([ i ^ 0x5c for i in bytearray(derivedKey)][:ALGORITHMS_DATA[self['HashAlgo']][4]]) derivedKey = ALGORITHMS_DATA[self['HashAlgo']][1].new(ipad).digest() + \ ALGORITHMS_DATA[self['HashAlgo']][1].new(opad).digest() derivedKey = fixparity(derivedKey) return derivedKey
def decrypt(secretkey, params): iv = b64decode(params['iv']) salt = b64decode(params['salt']) #~ keylen = params.get('ks', 128) // 8 # FIXME use somewhere? taglen = params.get('ts', 64) // 8 iterations = params.get('iter', 1000) data = b64decode(params['ct']) ciphertext = data[:-taglen] tag = data[-taglen:] if params.get('adata'): raise NotImplementedError('authenticated data support is not implemented') iv = trunc_iv(iv, ciphertext, taglen) hash_func = lambda k, s: HMAC.new(k, s, SHA256).digest() key = PBKDF2(secretkey, salt=salt, count=iterations, prf=hash_func) mode_str = params.get('mode', 'ccm') mode = dict(ccm=AES.MODE_CCM)[mode_str] if mode_str == 'ccm': cipher = AES.new(key, mode=AES.MODE_CCM, nonce=iv, mac_len=taglen) else: cipher = AES.new(key, mode=mode, iv=iv) decrypted = cipher.decrypt_and_verify(ciphertext, tag) return decrypted
def encrypt(plaintext): iv = urandom(16) salt = urandom(8) iterations = 1000 ks = 128 ts = 64 hash_func = lambda k, s: HMAC.new(k, s, SHA256).digest() password = b64encode(urandom(32)) key = PBKDF2(password, salt=salt, count=iterations, prf=hash_func) smalliv = trunc_iv(iv, plaintext, 0) cipher = AES.new(key, mode=AES.MODE_CCM, nonce=smalliv, mac_len=ts // 8) ciphertext = b''.join(cipher.encrypt_and_digest(plaintext)) # OrderedDict because 0bin is a piece of shit requiring "iv" as the first key return password.decode('ascii'), OrderedDict([ ('iv', b64encode(iv).decode('ascii')), ('v', 1), ('iter', iterations), ('ks', ks), ('ts', ts), ('mode', 'ccm'), ('adata', ''), ('cipher', 'aes'), ('salt', b64encode(salt).decode('ascii')), ('ct', b64encode(ciphertext).decode('ascii')), ])
def aes_cbc_hmac_encrypt(key, iv, aad, pt): """ Perform authenticated encryption with the combined AES-CBC and HMAC algorithm. :param key: key; length MUST be 32, 48, or 64 octets :param iv: Initialization vector; length MUST be 16 octets :param aad: Additional authenticated data :param pt: Plaintext :return: (ciphertext, tag) tuple, with each as bytes """ ka, ke, seclen, dgst = get_keys_seclen_dgst(key, iv) # Encrypt cipher = AES.new(ke, AES.MODE_CBC, iv) ct = cipher.encrypt(pkcs5pad(pt)) # MAC A || IV || E || AL al = pack("!Q", 8*len(aad)) mac_input = aad + iv + ct + al h = HMAC.new(ka, digestmod=dgst) h.update(mac_input) tag = h.digest()[:seclen] return ct, tag
def encrypt(cls, key, keyusage, plaintext, confounder): ki = cls.derive(key, pack('>IB', keyusage, 0x55)) ke = cls.derive(key, pack('>IB', keyusage, 0xAA)) if confounder is None: confounder = get_random_bytes(cls.blocksize) basic_plaintext = confounder + _zeropad(plaintext, cls.padsize) hmac = HMAC.new(ki.contents, basic_plaintext, cls.hashmod).digest() return cls.basic_encrypt(ke, basic_plaintext) + hmac[:cls.macsize]
def decrypt(self, key, entropy = None): keyHash = SHA1.new(key).digest() sessionKey = HMAC.new(keyHash, self['Salt'], ALGORITHMS_DATA[self['HashAlgo']][1]) if entropy is not None: sessionKey.update(entropy) sessionKey = sessionKey.digest() # Derive the key derivedKey = self.deriveKey(sessionKey) cipher = ALGORITHMS_DATA[self['CryptAlgo']][1].new(derivedKey[:ALGORITHMS_DATA[self['CryptAlgo']][0]], mode=ALGORITHMS_DATA[self['CryptAlgo']][2], iv=b'\x00'*ALGORITHMS_DATA[self['CryptAlgo']][3]) cleartext = unpad(cipher.decrypt(self['Data']), ALGORITHMS_DATA[self['CryptAlgo']][1].block_size) # Now check the signature # ToDo Fix this, it's just ugly, more testing so we can remove one toSign = (self.rawData[20:][:len(self.rawData)-20-len(self['Sign'])-4]) # Calculate the different HMACKeys keyHash2 = keyHash + b"\x00"*ALGORITHMS_DATA[self['HashAlgo']][1].block_size ipad = bytearray([i ^ 0x36 for i in bytearray(keyHash2)][:ALGORITHMS_DATA[self['HashAlgo']][1].block_size]) opad = bytearray([i ^ 0x5c for i in bytearray(keyHash2)][:ALGORITHMS_DATA[self['HashAlgo']][1].block_size]) a = ALGORITHMS_DATA[self['HashAlgo']][1].new(ipad) a.update(self['HMac']) hmacCalculated1 = ALGORITHMS_DATA[self['HashAlgo']][1].new(opad) hmacCalculated1.update(a.digest()) if entropy is not None: hmacCalculated1.update(entropy) hmacCalculated1.update(toSign) hmacCalculated3 = HMAC.new(keyHash, self['HMac'], ALGORITHMS_DATA[self['HashAlgo']][1]) if entropy is not None: hmacCalculated3.update(entropy) hmacCalculated3.update(toSign) if hmacCalculated1.digest() == self['Sign'] or hmacCalculated3.digest() == self['Sign']: return cleartext else: return None
def decrypt(cls, key, keyusage, ciphertext): if len(ciphertext) < 24: raise ValueError('ciphertext too short') cksum, basic_ctext = bytearray(ciphertext[:16]), bytearray(ciphertext[16:]) ki = HMAC.new(key.contents, cls.usage_str(keyusage), MD5).digest() ke = HMAC.new(ki, cksum, MD5).digest() basic_plaintext = bytearray(ARC4.new(ke).decrypt(bytes(basic_ctext))) exp_cksum = bytearray(HMAC.new(ki, basic_plaintext, MD5).digest()) ok = _mac_equal(cksum, exp_cksum) if not ok and keyusage == 9: # Try again with usage 8, due to RFC 4757 errata. ki = HMAC.new(key.contents, pack('<I', 8), MD5).digest() exp_cksum = HMAC.new(ki, basic_plaintext, MD5).digest() ok = _mac_equal(cksum, exp_cksum) if not ok: raise InvalidChecksum('ciphertext integrity failure') # Discard the confounder. return bytes(basic_plaintext[8:])
def master(master_key,sid,password): #master_key fp = open(master_key, 'rb') data = fp.read() mkf= MasterKeyFile(data) mkf.dump() fp.close() data = data[len(mkf):] mk = MasterKey(data[:mkf['MasterKeyLen']]) # Will generate two keys, one with SHA1 and another with MD4 key1 = HMAC.new(SHA1.new(password.encode('utf-16le')).digest(), (sid + '\0').encode('utf-16le'), SHA1).digest() key2 = HMAC.new(MD4.new(password.encode('utf-16le')).digest(), (sid + '\0').encode('utf-16le'), SHA1).digest() # For Protected users tmpKey = pbkdf2_hmac('sha256', MD4.new(password.encode('utf-16le')).digest(), sid.encode('utf-16le'), 10000) tmpKey2 = pbkdf2_hmac('sha256', tmpKey, sid.encode('utf-16le'), 1)[:16] key3 = HMAC.new(tmpKey2, (sid + '\0').encode('utf-16le'), SHA1).digest()[:20] #/key1, key2, key3 = self.deriveKeysFromUser(self.options.sid, password) # if mkf['flags'] & 4 ? SHA1 : MD4 decryptedKey = mk.decrypt(key3) if decryptedKey: print('Decrypted key with User Key (MD4 protected)') print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1')) return decryptedKey decryptedKey = mk.decrypt(key2) if decryptedKey: print('Decrypted key with User Key (MD4)') print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1')) return decryptedKey decryptedKey = mk.decrypt(key1) if decryptedKey: print('Decrypted key with User Key (SHA1)') print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1')) return decryptedKey
def authenticated_encrypt(aes_key, hmac_key, data): data = Padding.pad(data, AES.block_size, style='pkcs7') iv = Random.new().read(AES.block_size) # create random IV ciphertext = iv + AES.new(aes_key, AES.MODE_CBC, iv).encrypt( data.encode('utf-8')) # encrypt the data using AES in CBC # tag the encrypted data using HMAC-SHA256 hmac = HMAC.new(hmac_key, digestmod=SHA256) hmac.update(ciphertext) tag = hmac.hexdigest() return base64.b64encode(ciphertext + tag)
def test3(self): # Verify that hmac_hash_module works like prf password = b("xxx") salt = b("yyy") for hashmod in (MD5, SHA1, SHA224, SHA256, SHA384, SHA512): pr1 = PBKDF2(password, salt, 16, 100, prf=lambda p, s: HMAC.new(p,s,hashmod).digest()) pr2 = PBKDF2(password, salt, 16, 100, hmac_hash_module=hashmod) self.assertEqual(pr1, pr2)
def test3(self): # Verify that hmac_hash_module works like prf password = b("xxx") salt = b("yyy") for hashmod in (MD5, SHA1, SHA224, SHA256, SHA384, SHA512): pr1 = PBKDF2(password, salt, 16, 100, prf=lambda p, s: HMAC.new(p,s,hashmod).digest()) pr2 = PBKDF2(password, salt, 16, 100, hmac_hash_module=hashmod) self.assertEqual(pr1, pr2)
def cryptodome(): import Cryptodome from Cryptodome.Hash import MD2 from Cryptodome.Hash import MD4 from Cryptodome.Hash import MD5 from Cryptodome.Hash import SHA1 from Cryptodome.Hash import SHA224 from Cryptodome.Hash import SHA256 from Cryptodome.Hash import SHA384 from Cryptodome.Hash import SHA512 from Cryptodome.Hash import HMAC Cryptodome.Hash.MD2.new() # Noncompliant MD2.new() # Noncompliant MD4.new() # Noncompliant MD5.new() # Noncompliant SHA1.new() # Noncompliant SHA224.new() # Noncompliant SHA256.new() # OK SHA384.new() # OK SHA512.new() # OK HMAC.new(b"\x00") # OK
def generateHMAC(message): key_file = open("HMAC_key_file.bin", "rb") key = key_file.read(16) key_file.close() h = HMAC.new(key, digestmod=SHA256) h.update(message.encode('utf-8')) hmac = h.hexdigest().encode('utf-8') #Corrupt HMAC: #hmac += "4".encode('utf-8') print("Generated HMAC:" + str(hmac)) # Send message and HMAC to server send("1#####" + message + "#####" + hmac.decode('latin-1'))
def _compute_nonce(self, mhash): """Generate k in a deterministic way""" # See section 3.2 in RFC6979.txt # Step a h1 = mhash.digest() # Step b mask_v = bchr(1) * mhash.digest_size # Step c nonce_k = bchr(0) * mhash.digest_size for int_oct in 0, 1: # Step d/f nonce_k = HMAC.new(nonce_k, mask_v + bchr(int_oct) + self._int2octets(self._private_key) + self._bits2octets(h1), mhash).digest() # Step e/g mask_v = HMAC.new(nonce_k, mask_v, mhash).digest() nonce = -1 while not (0 < nonce < self._order): # Step h.C (second part) if nonce != -1: nonce_k = HMAC.new(nonce_k, mask_v + bchr(0), mhash).digest() mask_v = HMAC.new(nonce_k, mask_v, mhash).digest() # Step h.A mask_t = b("") # Step h.B while len(mask_t) < self._order_bytes: mask_v = HMAC.new(nonce_k, mask_v, mhash).digest() mask_t += mask_v # Step h.C (first part) nonce = self._bits2int(mask_t) return nonce
def pycrypto(): import Crypto from Crypto.Hash import MD2 from Crypto.Hash import MD4 from Crypto.Hash import MD5 from Crypto.Hash import SHA from Crypto.Hash import SHA224 from Crypto.Hash import SHA256 from Crypto.Hash import SHA384 from Crypto.Hash import SHA512 from Crypto.Hash import HMAC Crypto.Hash.MD2.new() # Noncompliant MD2.new() # Noncompliant MD4.new() # Noncompliant MD5.new() # Noncompliant SHA.new() # Noncompliant SHA224.new() # Noncompliant SHA256.new() # Noncompliant SHA384.new() # Noncompliant SHA512.new() # Noncompliant HMAC.new(b"\x00") # Noncompliant
def _compute_nonce(self, mhash): """Generate k in a deterministic way""" # See section 3.2 in RFC6979.txt # Step a h1 = mhash.digest() # Step b mask_v = b'\x01' * mhash.digest_size # Step c nonce_k = b'\x00' * mhash.digest_size for int_oct in (b'\x00', b'\x01'): # Step d/f nonce_k = HMAC.new(nonce_k, mask_v + int_oct + self._int2octets(self._private_key) + self._bits2octets(h1), mhash).digest() # Step e/g mask_v = HMAC.new(nonce_k, mask_v, mhash).digest() nonce = -1 while not (0 < nonce < self._order): # Step h.C (second part) if nonce != -1: nonce_k = HMAC.new(nonce_k, mask_v + b'\x00', mhash).digest() mask_v = HMAC.new(nonce_k, mask_v, mhash).digest() # Step h.A mask_t = b"" # Step h.B while len(mask_t) < self._order_bytes: mask_v = HMAC.new(nonce_k, mask_v, mhash).digest() mask_t += mask_v # Step h.C (first part) nonce = self._bits2int(mask_t) return nonce
def run(self): assert self.outbox is not None # get client id and retrieve its entry mel, KA = self.inbox.get() assert mel in self.DB salt, KX = self.DB[mel] # B = k*KX + KB # linear mix of the pwd "pub." key with the server "pub." key B = (self.k * KX + self.KB) % self.N self.outbox.put((salt, B)) u = int.from_bytes( SHA256.new(int_to_bytes(KA) + int_to_bytes(B)).digest(), 'big') sec = pow(KA * pow(KX, u, self.N), self.Kb, self.N) # sec = g^((Ka+Kx*u)*Kb) key = SHA256.new(int_to_bytes(sec)).digest() print('Server: sec', sec) print('Server: key', key.hex()) mac = self.inbox.get() HMAC.new(key, salt, SHA256).verify(mac) print('Server: ok') self.outbox.put(b'OK') print('Server: done')
def loads(cls, data, store_password, try_decrypt_keys=True): """ See :meth:`jks.jks.KeyStore.loads`. :param bytes data: Byte string representation of the keystore to be loaded. :param str password: Keystore password string :param bool try_decrypt_keys: Whether to automatically try to decrypt any encountered key entries using the same password as the keystore password. :returns: A loaded :class:`BksKeyStore` instance, if the keystore could be successfully parsed and the supplied store password is correct. If the ``try_decrypt_keys`` parameters was set to ``True``, any keys that could be successfully decrypted using the store password have already been decrypted; otherwise, no atttempt to decrypt any key entries is made. :raises BadKeystoreFormatException: If the keystore is malformed in some way :raises UnsupportedKeystoreVersionException: If the keystore contains an unknown format version number :raises KeystoreSignatureException: If the keystore signature could not be verified using the supplied store password :raises DuplicateAliasException: If the keystore contains duplicate aliases """ try: pos = 0 version = b4.unpack_from(data, pos)[0]; pos += 4 if version not in [1,2]: raise UnsupportedKeystoreVersionException("Unsupported BKS keystore version; only V1 and V2 supported, found v"+repr(version)) salt, pos = cls._read_data(data, pos) iteration_count = b4.unpack_from(data, pos)[0]; pos += 4 store_type = "bks" entries, size = cls._load_bks_entries(data[pos:], store_type, store_password, try_decrypt_keys=try_decrypt_keys) hmac_fn = hashlib.sha1 hmac_digest_size = hmac_fn().digest_size hmac_key_size = hmac_digest_size*8 if version != 1 else hmac_digest_size hmac_key = rfc7292.derive_key(hmac_fn, rfc7292.PURPOSE_MAC_MATERIAL, store_password, salt, iteration_count, hmac_key_size//8) store_data = data[pos:pos+size] store_hmac = data[pos+size:pos+size+hmac_digest_size] if len(store_hmac) != hmac_digest_size: raise BadKeystoreFormatException("Bad HMAC size; found %d bytes, expected %d bytes" % (len(store_hmac), hmac_digest_size)) hmac = HMAC.new(hmac_key, digestmod=SHA) hmac.update(store_data) computed_hmac = hmac.digest() if store_hmac != computed_hmac: raise KeystoreSignatureException("Hash mismatch; incorrect keystore password?") return cls(store_type, entries, version=version) except struct.error as e: raise BadKeystoreFormatException(e)
def produce_search_tokens(keyword): """ When the client wants to search, they need to compute a search token tk = (tk1,tk2) = (PRP(w,key_p),PRF(w,key_f)). This function finds that token. """ keyword = pkcs7_pad(keyword.lower().encode()) PRP = AES.new(key_p, AES.MODE_CBC, iv) tk1 = PRP.encrypt(keyword) PRF = HMAC.new(key_f, digestmod=SHA256) PRF.update(keyword) tk2 = PRF.digest() return tk1, tk2
def dataDecrypt(cipherAlgo, hashAlgo, raw, encKey, iv, rounds): """Internal use. Decrypts data stored in DPAPI structures.""" if hashAlgo == ALGORITHMS.CALG_HMAC.value: hashModule = SHA1 else: hashModule = ALGORITHMS_DATA[hashAlgo][1] prf = lambda p, s: HMAC.new(p, s, hashModule).digest() derived = deriveKey(encKey, iv, ALGORITHMS_DATA[cipherAlgo][0] + ALGORITHMS_DATA[cipherAlgo][3], count=rounds, hashFunction=prf) key, iv = derived[:ALGORITHMS_DATA[cipherAlgo][0]], derived[ALGORITHMS_DATA[cipherAlgo][0]:] key = key[:ALGORITHMS_DATA[cipherAlgo][0]] iv = iv[:ALGORITHMS_DATA[cipherAlgo][3]] cipher = ALGORITHMS_DATA[cipherAlgo][1].new(key, mode=ALGORITHMS_DATA[cipherAlgo][2], IV=iv) cleartxt = cipher.decrypt(raw) return cleartxt
def decrypt(cls, key, keyusage, ciphertext): ki = cls.derive(key, pack('>IB', keyusage, 0x55)) ke = cls.derive(key, pack('>IB', keyusage, 0xAA)) if len(ciphertext) < cls.blocksize + cls.macsize: raise ValueError('ciphertext too short') basic_ctext, mac = bytearray(ciphertext[:-cls.macsize]), bytearray(ciphertext[-cls.macsize:]) if len(basic_ctext) % cls.padsize != 0: raise ValueError('ciphertext does not meet padding requirement') basic_plaintext = cls.basic_decrypt(ke, bytes(basic_ctext)) hmac = bytearray(HMAC.new(ki.contents, basic_plaintext, cls.hashmod).digest()) expmac = hmac[:cls.macsize] if not _mac_equal(mac, expmac): raise InvalidChecksum('ciphertext integrity failure') # Discard the confounder. return bytes(basic_plaintext[cls.blocksize:])
def verifyHMAC(message, hmac): print("RECIEVED FROM CLIENT...") print("Message: " + shorten(message)) print("HMAC: " + shorten(str(hmac))) h = HMAC.new(HMAC_key, digestmod=SHA256) h.update(message.encode('utf-8')) try: h.hexverify(hmac) result = "The message is authentic" except ValueError: result = "The message or key is invalid" print(result) return result
def run(self): assert self.outbox is not None self.outbox.put((self.mel, self.KA)) salt, KB, u = self.inbox.get() # using the salt, retrieve the server db entry key Kx = int.from_bytes(SHA256.new(salt + self.pwd).digest(), 'big') sec = pow(KB, self.Ka + u * Kx, self.N) # sec = KB^(Ka+u*Kx) = g^(Kb*(Ka+u*Kx)) key = SHA256.new(int_to_bytes(sec)).digest() print('Client: key', key.hex()) mac = HMAC.new(key, salt, SHA256).digest() self.outbox.put(mac) ok = self.inbox.get() assert ok == b'OK' print('Client: ok, done')
def shared_key_sign(data, key): if not isinstance(data, bytes): serial_data = pickle.dumps(data) else: serial_data = data alg = key['alg'] k = key['key'] hash_alg = hash_modules[key['hash']] if alg == 'hmac': h = HMAC.new(k, digestmod=hash_alg) h.update(serial_data) sig = h.digest() return sig else: print('SA_ERROR:', alg, 'not yet implemented.', flush=True)
def decrypt(cls, key, keyusage, ciphertext): ki = cls.derive(key, pack('>IB', keyusage, 0x55)) ke = cls.derive(key, pack('>IB', keyusage, 0xAA)) if len(ciphertext) < cls.blocksize + cls.macsize: raise ValueError('ciphertext too short') basic_ctext, mac = ciphertext[:-cls.macsize], ciphertext[-cls.macsize:] if len(basic_ctext) % cls.padsize != 0: raise ValueError('ciphertext does not meet padding requirement') basic_plaintext = cls.basic_decrypt(ke, basic_ctext) hmac = HMAC.new(ki.contents, basic_plaintext, cls.hashmod).digest() expmac = hmac[:cls.macsize] if not _mac_equal(mac, expmac): raise InvalidChecksum('ciphertext integrity failure') # Discard the confounder. return basic_plaintext[cls.blocksize:]
def ComputeResponsev2( NegFlg, ResponseKeyNT, ResponseKeyLM, ServerChallenge, ClientChallenge, Time=None, ServerName=None, av_pairs=None, ): if Time is None: Time = nttime.NtTime(nttime.datetime.now()) if ServerName is None: ServerName = "SERVER" ServerName = ServerName.encode("utf-16-le") TimeBuf = array.array("B") cur = core.Cursor(TimeBuf, 0) cur.encode_uint64le(Time) Responseversion = "\x01" HiResponseversion = "\x01" ntlmv2_client_challenge = NTLMv2ClientChallenge() ntlmv2_client_challenge.time_stamp = Time ntlmv2_client_challenge.challenge_from_client = ClientChallenge if av_pairs is not None: ntlmv2_client_challenge.av_pairs = av_pairs temp = encode_frame(ntlmv2_client_challenge).tobytes() NTProofStr = HMAC.new(ResponseKeyNT, ServerChallenge + temp, MD5).digest() NtChallengeResponse = NTProofStr + temp LmChallengeResponse = (HMAC.new( ResponseKeyLM, ServerChallenge + ClientChallenge, MD5).digest() + ClientChallenge) SessionBaseKey = HMAC.new(ResponseKeyNT, NTProofStr, MD5).digest() return NtChallengeResponse, LmChallengeResponse, SessionBaseKey
def decrypt(self, encrypted_input, validate, nonce): """ Decrypts given encrypted message and validates message with HMAC and nonce from encryption. :param encrypted_input: encrypted string to be decrypted. :param validate: HMAC validation byte string. :param nonce: nonce, additional security feature to prevent replay attacks. """ validation = HMAC.new(self.hmac_key, msg = encrypted_input, digestmod = SHA256) try: validation.hexverify(validate) except ValueError: client.disconnect(self) raise Exception("[FAIL]: Message is not authentic, failed HMAC validation!") pass ciphering = Salsa20.new(self.key, nonce = nonce) return ciphering.decrypt(encrypted_input)
def decrypt(self, key, entropy = None): keyHash = SHA1.new(key).digest() sessionKey = HMAC.new(keyHash, self['Salt'], ALGORITHMS_DATA[self['HashAlgo']][1]) if entropy is not None: sessionKey.update(entropy) sessionKey = sessionKey.digest() # Derive the key derivedKey = self.deriveKey(sessionKey) cipher = ALGORITHMS_DATA[self['CryptAlgo']][1].new(derivedKey[:ALGORITHMS_DATA[self['CryptAlgo']][0]], mode=ALGORITHMS_DATA[self['CryptAlgo']][2], iv=b'\x00'*ALGORITHMS_DATA[self['CryptAlgo']][3]) cleartext = unpad(cipher.decrypt(self['Data']), ALGORITHMS_DATA[self['CryptAlgo']][1].block_size) return cleartext '''
def authenticated_decrypt(aes_key, hmac_key, data): data = base64.b64decode(data) tag = data[-64:] data = data[:-64] # verify the HMAC tag hmac = HMAC.new(hmac_key, digestmod=SHA256) hmac.update(data) if tag != hmac.hexdigest(): raise AuthenticationError("failure") # decrypt the data using AES data = AES.new(aes_key, AES.MODE_CBC, data[:AES.block_size]).decrypt(data[AES.block_size:]) return Padding.unpad(data, AES.block_size, style='pkcs7')
def HMAC256_digest(secret, message, mode='base64'): """ This is the main HMAC256 digest function to encrypt the input message with the secret and turn it to hex digest. (or other modes) """ if type(secret) != bytes: secret = secret.encode() h = HMAC.new(secret, digestmod=SHA256) if message != bytes: message = message.encode() h.update(message) if mode != 'base64': return h.hexdigest() else: b64 = b64encode(bytes.fromhex(h.hexdigest())).decode() return b64
def run(self): assert self.outbox is not None self.KA = randint(0, 1 << 10) * self.N # KA = 0 mod N self.outbox.put((self.mel, self.KA)) salt, B = self.inbox.get() #u = int.from_bytes(SHA256.new(int_to_bytes(self.KA)+int_to_bytes(B)).digest(), 'big') # using the salt, retrieve the server db entry key #Kx = int.from_bytes(SHA256.new(salt+self.pwd).digest(), 'big') #KX = pow(self.g, Kx, self.N) #sec = pow(B-self.k*KX, self.Ka+u*Kx, self.N) sec = 0 key = SHA256.new(int_to_bytes(sec)).digest() print('Client: key', key.hex()) mac = HMAC.new(key, salt, SHA256).digest() self.outbox.put(mac) ok = self.inbox.get() assert ok == b'OK' print('Client: ok, done')
def KXKEY(NegFlg, SessionBaseKey, LmChallengeResponse, ServerChallenge, ResponseKeyLM): if NegFlg & NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY: hm = HMAC.new(SessionBaseKey, ServerChallenge + LmChallengeResponse[:8], MD5) KeyExchangeKey = hm.digest() else: LMOWF = ResponseKeyLM if NegFlg & NTLMSSP_NEGOTIATE_LMKEY: data = LmChallengeResponse[:8] KeyExchangeKey = DES(LMOWF[:7], data) + DES( LMOWF[8] + "\xbd" * 6, data) else: if NegFlg & NTLMSSP_REQUEST_NON_NT_SESSION_KEY: KeyExchangeKey = LMOWF[:8] + "\0" * 8 else: KeyExchangeKey = SessionBaseKey return KeyExchangeKey
def encrypt(self, byte_input): """ Takes byte input and returns encrypted input using a key and encryption nonce. :param byte_input: byte string to be encrypted. :return: encrypted string, nonce, and HMAC validation. """ if isinstance(byte_input, bytes): pass else: byte_input.encode(encoding="ascii", errors="replace") pass ciphering = Salsa20.new(self.key) validation = HMAC.new(self.hmac_key, msg=ciphering.encrypt(byte_input), digestmod=SHA256) return [ ciphering.encrypt(byte_input), ciphering.nonce, validation.hexdigest() ]
def __init__(self, pwd, nbits=256, force_wz_aes_version=None): if not pwd: raise RuntimeError('%s encryption requires a password.' % WZ_AES) if nbits not in (128, 192, 256): raise RuntimeError( "`nbits` must be one of 128, 192, 256. Got '%s'" % nbits) self.force_wz_aes_version = force_wz_aes_version salt_lengths = { 128: 8, 192: 12, 256: 16, } self.salt_length = salt_lengths[nbits] key_lengths = { 128: 16, 192: 24, 256: 32, } key_length = key_lengths[nbits] aes_strengths = { 128: 1, 192: 2, 256: 3, } self.aes_strength = aes_strengths[nbits] self.salt = Random.new().read(self.salt_length) pwd_verify_length = 2 dkLen = 2 * key_length + pwd_verify_length keymaterial = PBKDF2(pwd, self.salt, count=1000, dkLen=dkLen) self.encpwdverify = keymaterial[2 * key_length:] enckey = keymaterial[:key_length] self.encrypter = AES.new(enckey, AES.MODE_CTR, counter=Counter.new(nbits=128, little_endian=True)) encmac_key = keymaterial[key_length:2 * key_length] self.hmac = HMAC.new(encmac_key, digestmod=SHA1Hash())
def PBKDF2(password, salt, dkLen=16, count=1000, prf=None): """Derive one or more keys from a password (or passphrase). This function performs key derivation according to the PKCS#5 standard (v2.0). Args: password (string): The secret password to generate the key from. salt (string): A string to use for better protection from dictionary attacks. This value does not need to be kept secret, but it should be randomly chosen for each derivation. It is recommended to be at least 8 bytes long. dkLen (integer): The cumulative length of the desired keys. count (integer): The number of iterations to carry out. prf (callable): A pseudorandom function. It must be a function that returns a pseudorandom string from two parameters: a secret and a salt. If not specified, **HMAC-SHA1** is used. Return: A byte string of length ``dkLen`` that can be used as key material. If you wanted multiple keys, just break up this string into segments of the desired length. """ password = tobytes(password) if prf is None: prf = lambda p, s: HMAC.new(p, s, SHA1).digest() def link(s): s[0], s[1] = s[1], prf(password, s[1]) return s[0] key = b('') i = 1 while len(key) < dkLen: s = [prf(password, salt + struct.pack(">I", i))] * 2 key += reduce(strxor, (link(s) for j in range(count))) i += 1 return key[:dkLen]
def KXKEY(NegFlg, SessionBaseKey, LmChallengeResponse, ServerChallenge, ResponseKeyLM): if NegFlg & NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY: hm = HMAC.new(SessionBaseKey, ServerChallenge +\ LmChallengeResponse[:8], MD5) KeyExchangeKey = hm.digest() else: LMOWF = ResponseKeyLM if NegFlg & NTLMSSP_NEGOTIATE_LMKEY: data = LmChallengeResponse[:8] KeyExchangeKey = DES(LMOWF[:7], data) + \ DES(LMOWF[8] + "\xbd"*6, data) else: if NegFlg & NTLMSSP_REQUEST_NON_NT_SESSION_KEY: KeyExchangeKey = LMOWF[:8] + "\0"*8 else: KeyExchangeKey = SessionBaseKey return KeyExchangeKey
def encrypt(self, message): """Encrypts string of any length using the current crypto version Args: message: The string that needs to be encrypted. Returns: A serialized authenticated encrypted object """ iv = ''.join(chr(random.randint(0, 255)) for _ in range(self._aes_block_size)) aes = AES.new(PinballConfig.AES_CBC_KEY, AES.MODE_CBC, iv) hmac = HMAC.new(PinballConfig.HMAC_KEY, digestmod=SHA256) padded_length = (len(message) + self._aes_block_size - len(message) % (self._aes_block_size)) padded_message = message.ljust(padded_length, self._padding_char) ciphertext = aes.encrypt(padded_message) hmac.update(ciphertext) hmac.update(iv) return self._serialize(ciphertext, hmac.hexdigest(), iv=iv)
def PBKDF2(password, salt, dkLen=16, count=1000, prf=None): """Derive one or more keys from a password (or passphrase). This function performs key derivation according to the PKCS#5 standard (v2.0), by means of the ``PBKDF2`` algorithm. :Parameters: password : string The secret password or pass phrase to generate the key from. salt : string A string to use for better protection from dictionary attacks. This value does not need to be kept secret, but it should be randomly chosen for each derivation. It is recommended to be at least 8 bytes long. dkLen : integer The cumulative length of the desired keys. Default is 16 bytes, suitable for instance for `Cryptodome.Cipher.AES`. count : integer The number of iterations to carry out. It's recommended to use at least 1000. prf : callable A pseudorandom function. It must be a function that returns a pseudorandom string from two parameters: a secret and a salt. If not specified, HMAC-SHA1 is used. :Return: A byte string of length `dkLen` that can be used as key material. If you wanted multiple keys, just break up this string into segments of the desired length. """ password = tobytes(password) if prf is None: prf = lambda p,s: HMAC.new(p,s,SHA1).digest() def link(s): s[0], s[1] = s[1], prf(password, s[1]) return s[0] key = b('') i = 1 while len(key)<dkLen: s = [ prf(password, salt + struct.pack(">I", i)) ] * 2 key += reduce(strxor, (link(s) for j in range(count)) ) i += 1 return key[:dkLen]
async def wrapper(name:FormalName, sig:SignaturePtrs) -> bool: nonlocal secret sig_info = sig.signature_info covered_part = sig.signature_covered_part sig_value = sig.signature_value_buf if sig_info and sig_info.signature_type == SignatureType.HMAC_WITH_SHA256: if sig_info.key_locator.name != key_name: return False hmac_algo = HMAC.new(secret, digestmod=SHA256) if not covered_part or not sig_value: ret = False else: for blk in covered_part: hmac_algo.update(blk) try: hmac_algo.verify(sig_value) return True except ValueError: return False SVSyncLogger.debug(f'Digest check {Name.to_str(name)} -> {ret}') return ret return False
def __init__(self, secret, algorithm=None): if algorithm is None: algorithm = DEFAULT_SIGN_ALGORITHM assert algorithm in ALGORITHMS, "Unknown algorithm" if isinstance(secret, six.string_types): secret = secret.encode("ascii") self._rsa = None self._hash = None self.sign_algorithm, self.hash_algorithm = algorithm.split('-') if self.sign_algorithm == 'rsa': try: rsa_key = RSA.importKey(secret) self._rsa = PKCS1_v1_5.new(rsa_key) self._hash = HASHES[self.hash_algorithm] except ValueError: raise HttpSigException("Invalid key.") elif self.sign_algorithm == 'hmac': self._hash = HMAC.new(secret, digestmod=HASHES[self.hash_algorithm])
def __init__(self, zinfo, pwd, encryption_header): self.filename = zinfo.filename key_length = WZ_KEY_LENGTHS[zinfo.wz_aes_strength] salt_length = WZ_SALT_LENGTHS[zinfo.wz_aes_strength] salt = struct.unpack("<{}s".format(salt_length), encryption_header[:salt_length])[0] pwd_verify_length = 2 pwd_verify = encryption_header[salt_length:] dkLen = 2 * key_length + pwd_verify_length keymaterial = PBKDF2(pwd, salt, count=1000, dkLen=dkLen) encpwdverify = keymaterial[2 * key_length:] if encpwdverify != pwd_verify: raise RuntimeError("Bad password for file %r" % zinfo.filename) enckey = keymaterial[:key_length] self.decypter = AES.new(enckey, AES.MODE_CTR, counter=Counter.new(nbits=128, little_endian=True)) encmac_key = keymaterial[key_length:2 * key_length] self.hmac = HMAC.new(encmac_key, digestmod=SHA1Hash())
def test2(self): """From draft-josefsson-scrypt-kdf-01, Chapter 10""" output_1 = t2b(""" 55 ac 04 6e 56 e3 08 9f ec 16 91 c2 25 44 b6 05 f9 41 85 21 6d de 04 65 e6 8b 9d 57 c2 0d ac bc 49 ca 9c cc f1 79 b6 45 99 16 64 b3 9d 77 ef 31 7c 71 b8 45 b1 e3 0b d5 09 11 20 41 d3 a1 97 83 """) output_2 = t2b(""" 4d dc d8 f6 0b 98 be 21 83 0c ee 5e f2 27 01 f9 64 1a 44 18 d0 4c 04 14 ae ff 08 87 6b 34 ab 56 a1 d4 25 a1 22 58 33 54 9a db 84 1b 51 c9 b3 17 6a 27 2b de bb a1 d0 78 47 8f 62 b3 97 f3 3c 8d """) prf_hmac_sha256 = lambda p, s: HMAC.new(p, s, SHA256).digest() output = PBKDF2(b("passwd"), b("salt"), 64, 1, prf=prf_hmac_sha256) self.assertEqual(output, output_1) output = PBKDF2(b("Password"), b("NaCl"), 64, 80000, prf=prf_hmac_sha256) self.assertEqual(output, output_2)
def prf_SHA256(p,s): return HMAC.new(p,s,SHA256).digest()
def prf_SHA1(p,s): return HMAC.new(p,s,SHA1).digest()
def sign(self, msg, key): h = HMAC.new(key, msg, digestmod=self.digest) return h.digest()
def generate_hmac(key, nonce_or_iv): h = HMAC.new(key, digestmod=SHA256) def do_computation(msg: bytes): h.update(msg) # h.hexdigest() return do_computation
def checksum(cls, key, keyusage, text): ksign = HMAC.new(key.contents, b'signaturekey\0', MD5).digest() md5hash = MD5.new(_RC4.usage_str(keyusage) + text).digest() return HMAC.new(ksign, md5hash, MD5).digest()
def checksum(cls, key, keyusage, text): kc = cls.enc.derive(key, pack('>IB', keyusage, 0x99)) hmac = HMAC.new(kc.contents, text, cls.enc.hashmod).digest() return hmac[:cls.macsize]