def main(): key = 'secretkey' msg = input('Enter message: ') hmac = HMAC(key.encode('utf-8'), msg.encode('utf-8')) hashed = base64.b64encode(hmac.digest()) print('Hashed:', hashed) got = send_message(msg) check_hmac = HMAC(key.encode('utf-8'), got.encode('utf-8')) got_hashed = base64.b64encode(check_hmac.digest()) print('Is not corruped:', got_hashed == hashed)
def _create_empty(self, password): assert type(password) != unicode self.f_tag = "PWS3" self.f_salt = Vault._urandom(32) self.f_iter = 2048 stretched_password = self._stretch_password(password, self.f_salt, self.f_iter) self.f_sha_ps = hashlib.sha256(stretched_password).digest() cipher = TwofishECB(stretched_password) self.f_b1 = cipher.encrypt(Vault._urandom(16)) self.f_b2 = cipher.encrypt(Vault._urandom(16)) self.f_b3 = cipher.encrypt(Vault._urandom(16)) self.f_b4 = cipher.encrypt(Vault._urandom(16)) key_k = cipher.decrypt(self.f_b1) + cipher.decrypt(self.f_b2) key_l = cipher.decrypt(self.f_b3) + cipher.decrypt(self.f_b4) self.f_iv = Vault._urandom(16) hmac_checker = HMAC(key_l, "", hashlib.sha256) cipher = TwofishCBC(key_k, self.f_iv) # No records yet self.f_hmac = hmac_checker.digest()
def encrypt_and_hmac(self, packet): """ Encrypts and signs a Packet() using self.SK_ei and self.SK_ai :param packet: Unecrypted Packet() with one or more payloads. :return: Encrypted and signed Packet() with a single payloads.SK """ final = Packet(exchange_type=packet.exchange_type, iSPI=packet.iSPI, rSPI=packet.rSPI, message_id=1) # Set up crypto iv = os.urandom(16) ikecrypto = Camellia(self.SK_ei, iv) ikehash = HMAC(self.SK_ai, digestmod=sha256) logger.debug('IV: {}'.format(dump(iv))) # Encrypt plain = bytes(packet)[const.IKE_HEADER.size:] ciphertext = ikecrypto.encrypt(plain) sk = payloads.SK(next_payload=packet.payloads[0]._type, iv=iv, ciphertext=ciphertext) final.add_payload(sk) logger.debug(dump(bytes(final))) # Sign ikehash.update(bytes(final)[:-MACLEN]) mac = ikehash.digest()[:MACLEN] sk.mac(mac) logger.debug(dump(bytes(final))) return bytes(final)
def db_create_header(self, password, vault): vault.f_tag = self.db_version_tag vault.f_salt = vault.urandom(32) vault.f_iter = 2048 # Database version 4 uses one master password which is random generated # and secondary passwords to encrypt them. # XXX What about master normal password ? rand_p = random_password() rand_p.password_length = 32 master_passwd = rand_p.generate_password() stretched_master_password = vault._stretch_password(master_passwd, vault.f_salt, vault.f_iter) vault.f_sha_ps = hashlib.sha256(stretched_master_password).digest() cipher = TwofishECB(stretched_master_password) vault.f_b1 = cipher.encrypt(vault.urandom(16)) vault.f_b2 = cipher.encrypt(vault.urandom(16)) vault.f_b3 = cipher.encrypt(vault.urandom(16)) vault.f_b4 = cipher.encrypt(vault.urandom(16)) key_k = cipher.decrypt(vault.f_b1) + cipher.decrypt(vault.f_b2) key_l = cipher.decrypt(vault.f_b3) + cipher.decrypt(vault.f_b4) vault.f_iv = vault.urandom(16) hmac_checker = HMAC(key_l, "", hashlib.sha256) # No records yet vault.f_hmac = hmac_checker.digest() # Encrypt master password with user one stretched_user_pass = vault._stretch_password(password, vault.f_salt, vault.f_iter) user_cipher = TwofishECB(stretched_user_pass) self.db_v4_passwds = [{'auth': self.db_ptag[0], 'passwd': user_cipher.encrypt(stretched_master_password), 'orig': '1'}]
def verify_message_auth_code(our_mac, msg_mac, ses_key): ## two rounds closes a timing side-channel msg_mac = HMAC_FUNC(ses_key, msg_mac, HMAC_HASH) our_mac = HMAC_FUNC(ses_key, our_mac, HMAC_HASH) msg_mac = msg_mac.digest() our_mac = our_mac.digest() num_val = 0 if (len(msg_mac) != len(our_mac)): return False ## fixed linear-time comparison closes another for i in xrange(len(our_mac)): num_val += (our_mac[i] == msg_mac[i]) return (num_val == len(our_mac))
def _create_empty(self, password): assert type(password) != unicode self.f_tag = 'PWS3' self.f_salt = Vault._urandom(32) self.f_iter = 2048 stretched_password = self._stretch_password(password, self.f_salt, self.f_iter) self.f_sha_ps = hashlib.sha256(stretched_password).digest() cipher = TwofishECB(stretched_password) self.f_b1 = cipher.encrypt(Vault._urandom(16)) self.f_b2 = cipher.encrypt(Vault._urandom(16)) self.f_b3 = cipher.encrypt(Vault._urandom(16)) self.f_b4 = cipher.encrypt(Vault._urandom(16)) key_k = cipher.decrypt(self.f_b1) + cipher.decrypt(self.f_b2) key_l = cipher.decrypt(self.f_b3) + cipher.decrypt(self.f_b4) self.f_iv = Vault._urandom(16) hmac_checker = HMAC(key_l, "", hashlib.sha256) cipher = TwofishCBC(key_k, self.f_iv) # No records yet self.f_hmac = hmac_checker.digest()
def __findHashedHostname(self,hostname): for (key,salt,res) in self.hashes: hmac = HMAC(salt, None, sha1) hmac.update(hostname) ours = hmac.digest() if ours == res: return self.hosts.get(key) return None
def ae_stretch_iter(start, iterations): end = bytes(start) for i in range(iterations): hs = HMAC(keys[KEYNUM.pin_stretch], msg=end, digestmod=sha256) end = hs.digest() return end
def calculate_digest(secret, message, salt): """Calculate a SHA-256 HMAC digest for the given data.""" assert isinstance(secret, bytes), "%r is not a byte string." % (secret, ) assert isinstance(message, bytes), "%r is not byte string." % (message, ) assert isinstance(salt, bytes), "%r is not a byte string." % (salt, ) hmacr = HMAC(secret, digestmod=sha256) hmacr.update(message) hmacr.update(salt) return hmacr.digest()
def response(self, challenge): if(self.server_signature): self.evaluateOutcome(challenge) return "" else: serverChallenge, salt, iterations = challenge.split(",") self.server_nonce = serverChallenge[2:] if self.server_nonce.find(self.client_nonce) != 0: raise SaslException("Server nonce does not start with client nonce") self.salt = base64.b64decode(salt[2:]) iterations = int(iterations[2:]) hmac = HMAC(key=self.password.replace("=","=3D").replace(",","=2C"),digestmod=self.algorithm) hmac.update(self.salt) hmac.update("\x00\x00\x00\x01") saltedPassword = hmac.digest() previous = saltedPassword for i in range(1,iterations): hmac = HMAC(key=self.password.replace("=","=3D").replace(",","=2C"),digestmod=self.algorithm) hmac.update(previous) previous = hmac.digest() saltedPassword = ''.join(chr(ord(a) ^ ord(b)) for a,b in zip(saltedPassword,previous)) clientFinalMessageWithoutProof = "c=" + base64.b64encode("n,,") + ",r=" + self.server_nonce authMessage = self.client_first_message + "," + challenge + "," + clientFinalMessageWithoutProof clientKey = HMAC(key=saltedPassword,msg="Client Key",digestmod=self.algorithm).digest() hashFunc = self.algorithm() hashFunc.update(clientKey) storedKey = hashFunc.digest() clientSignature = HMAC(key=storedKey, msg=authMessage, digestmod=self.algorithm).digest() clientProof = ''.join(chr(ord(a) ^ ord(b)) for a,b in zip(clientKey,clientSignature)) serverKey = HMAC(key=saltedPassword,msg="Server Key",digestmod=self.algorithm).digest() self.server_signature = HMAC(key=serverKey,msg=authMessage,digestmod=self.algorithm).digest() return clientFinalMessageWithoutProof + ",p=" + base64.b64encode(clientProof)
def encrypt_sign_bytes(self, raw_msg, encode_func = base64.b64encode): assert(type(raw_msg) == str) ## encrypt, then sign (HMAC = H((K ^ O) | H((K ^ I) | M))) enc_msg = self.encrypt_encode_bytes(raw_msg, null_encode) msg_mac = HMAC_FUNC(self.get_key(), enc_msg, HMAC_HASH) msg_mac = encode_func(msg_mac.digest()) enc_msg = encode_func(enc_msg) return (enc_msg, msg_mac)
def sas(sbNamespace,sbEntityPath,sharedAccessKey,sharedAccessKeyName): uri = "http://" + sbNamespace + ".servicebus.windows.net/" + sbEntityPath encodedResourceUri = quote_plus(uri) expireInSeconds = floor( time.time() + 300 + .5 ) plainSignature = encodedResourceUri + "\n" + str(expireInSeconds) plainSignature = plainSignature.encode('utf-8') signed_hmac_sha256 = HMAC(sharedAccessKey,plainSignature,sha256) digest = signed_hmac_sha256.digest() encoded_digest = b64encode(digest) return "SharedAccessSignature sig=%s&se=%s&skn=%s&sr=%s" % (quote_plus(encoded_digest),expireInSeconds, sharedAccessKeyName, encodedResourceUri)
def _sign(self, stringToSign): """ Sign a request using the secret key. Reference: U{http://docs.amazonwebservices.com/AmazonS3/latest/dev/RESTAuthentication.html} @param stringToSign: the string to sign for the request @type stringToSign: str @return: Amazon S3-required HMAC signature @rtype: str """ h=HMAC(self.secretKey, digestmod=sha1) h.update(stringToSign) return base64.b64encode(h.digest())
def sas(sbNamespace, sbEntityPath, sharedAccessKey, sharedAccessKeyName): uri = "http://" + sbNamespace + ".servicebus.windows.net/" + sbEntityPath encodedResourceUri = quote_plus(uri) expireInSeconds = floor(time.time() + 300 + .5) plainSignature = encodedResourceUri + "\n" + str(expireInSeconds) plainSignature = plainSignature.encode('utf-8') signed_hmac_sha256 = HMAC(sharedAccessKey, plainSignature, sha256) digest = signed_hmac_sha256.digest() encoded_digest = b64encode(digest) return "SharedAccessSignature sig=%s&se=%s&skn=%s&sr=%s" % ( quote_plus(encoded_digest), expireInSeconds, sharedAccessKeyName, encodedResourceUri)
def verify_hmac(self, data): """ Verifies the HMAC signature of an encrypted (SK, 46) payload using self.SK_ar :param data: bytes(payloads.SK()) :raise IkeError: if calculated signature does not match the one in the payload """ hmac = HMAC(self.SK_ar, digestmod=sha256) hmac_theirs = data[-MACLEN:] hmac.update(data[:-MACLEN]) hmac_ours = hmac.digest()[:MACLEN] logger.debug('HMAC verify (ours){} (theirs){}'.format( binascii.hexlify(hmac_ours), binascii.hexlify(hmac_theirs))) if hmac_ours != hmac_theirs: raise IkeError('HMAC verify failed')
def auth_decrypt_bytes(self, enc_msg, msg_mac, decode_func=base64.b64decode): assert type(enc_msg) == str assert type(msg_mac) == str # auth, then decrypt msg_mac = decode_func(msg_mac) enc_msg = decode_func(enc_msg) our_mac = HMAC_FUNC(self.get_key(), enc_msg, HMAC_HASH) our_mac = our_mac.digest() if verify_message_auth_code(our_mac, msg_mac, self.get_key()): return self.decode_decrypt_bytes(enc_msg, null_decode) # counts as false return ""
def ae_mixin_key(keynum, start): if keynum: hm = HMAC(keys[keynum], msg=start, digestmod=sha256) end = hm.digest() else: end = bytes(32) md = sha256() md.update(keys[KEYNUM.pairing]) md.update(start) md.update(bytes([keynum])) md.update(end) return md.digest()
def auth_decrypt_bytes(self, enc_msg, msg_mac, decode_func=base64.b64decode): assert (type(enc_msg) == str) assert (type(msg_mac) == str) ## auth, then decrypt msg_mac = decode_func(msg_mac) enc_msg = decode_func(enc_msg) our_mac = HMAC_FUNC(self.get_key(), enc_msg, HMAC_HASH) our_mac = our_mac.digest() if (verify_message_auth_code(our_mac, msg_mac, self.get_key())): return (self.decode_decrypt_bytes(enc_msg, null_decode)) ## counts as false return ""
def db_create_header(self, password, vault): vault.f_tag = self.db_version_tag vault.f_salt = vault.urandom(32) vault.f_iter = 2048 stretched_password = vault._stretch_password(password, vault.f_salt, vault.f_iter) vault.f_sha_ps = hashlib.sha256(stretched_password).digest() cipher = TwofishECB(stretched_password) vault.f_b1 = cipher.encrypt(vault.urandom(16)) vault.f_b2 = cipher.encrypt(vault.urandom(16)) vault.f_b3 = cipher.encrypt(vault.urandom(16)) vault.f_b4 = cipher.encrypt(vault.urandom(16)) key_k = cipher.decrypt(vault.f_b1) + cipher.decrypt(vault.f_b2) key_l = cipher.decrypt(vault.f_b3) + cipher.decrypt(vault.f_b4) vault.f_iv = vault.urandom(16) hmac_checker = HMAC(key_l, "", hashlib.sha256) # No records yet vault.f_hmac = hmac_checker.digest()
def sign_policy(self, key): hmac = HMAC(key, self.base64_policy(), hashlib.sha1) return base64.b64encode(hmac.digest())
def prf(key, data, hash_algorithm='sha256'): hasher = getattr(hashlib, hash_algorithm) m = HMAC(key, digestmod=hasher) m.update(data) return m.digest()
def response(self, challenge): if (self.server_signature): self.evaluateOutcome(challenge) return "" else: serverChallenge, salt, iterations = challenge.split(",") self.server_nonce = serverChallenge[2:] if self.server_nonce.find(self.client_nonce) != 0: raise SaslException( "Server nonce does not start with client nonce") self.salt = base64.b64decode(salt[2:]) iterations = int(iterations[2:]) hmac = HMAC(key=self.password.replace("=", "=3D").replace(",", "=2C"), digestmod=self.algorithm) hmac.update(self.salt) hmac.update("\x00\x00\x00\x01") saltedPassword = hmac.digest() previous = saltedPassword for i in range(1, iterations): hmac = HMAC(key=self.password.replace("=", "=3D").replace( ",", "=2C"), digestmod=self.algorithm) hmac.update(previous) previous = hmac.digest() saltedPassword = ''.join( chr(ord(a) ^ ord(b)) for a, b in zip(saltedPassword, previous)) clientFinalMessageWithoutProof = "c=" + base64.b64encode( "n,,") + ",r=" + self.server_nonce authMessage = self.client_first_message + "," + challenge + "," + clientFinalMessageWithoutProof clientKey = HMAC(key=saltedPassword, msg="Client Key", digestmod=self.algorithm).digest() hashFunc = self.algorithm() hashFunc.update(clientKey) storedKey = hashFunc.digest() clientSignature = HMAC(key=storedKey, msg=authMessage, digestmod=self.algorithm).digest() clientProof = ''.join( chr(ord(a) ^ ord(b)) for a, b in zip(clientKey, clientSignature)) serverKey = HMAC(key=saltedPassword, msg="Server Key", digestmod=self.algorithm).digest() self.server_signature = HMAC(key=serverKey, msg=authMessage, digestmod=self.algorithm).digest() return clientFinalMessageWithoutProof + ",p=" + base64.b64encode( clientProof)
def auth_decrypt_bytes_utf8(self, (enc_msg, msg_mac), decode_func = base64.b64decode): return (self.auth_decrypt_bytes((enc_msg.encode(UNICODE_ENCODING), msg_mac.encode(UNICODE_ENCODING)), decode_func)) def encrypt_sign_bytes(self, raw_msg, encode_func = base64.b64encode): assert(type(raw_msg) == str) ## encrypt, then sign (HMAC = H((K ^ O) | H((K ^ I) | M))) enc_msg = self.encrypt_encode_bytes(raw_msg, null_encode) msg_mac = HMAC_FUNC(self.get_key(), enc_msg, HMAC_HASH) msg_mac = encode_func(msg_mac.digest()) enc_msg = encode_func(enc_msg) return (enc_msg, msg_mac) def auth_decrypt_bytes(self, (enc_msg, msg_mac), decode_func = base64.b64decode): assert(type(enc_msg) == str) assert(type(msg_mac) == str) ## auth, then decrypt msg_mac = decode_func(msg_mac) enc_msg = decode_func(enc_msg) our_mac = HMAC_FUNC(self.get_key(), enc_msg, HMAC_HASH) our_mac = our_mac.digest() if (verify_message_auth_code(our_mac, msg_mac, self.get_key())): return (self.decode_decrypt_bytes(enc_msg, null_decode)) ## counts as false return ""
def create_hmac(secret, str_to_encode): new_hmac = HMAC(secret.encode(encoding=utf8), str_to_encode.encode(encoding=utf8), hashlib.sha256) return b64encode(new_hmac.digest())
def _read_from_file(self, filename, password): """ Initialize all class members by loading the contents of a Vault stored in the given file. """ assert type(password) != str ver3 = VaultVer3() ver4 = VaultVer4() # Read begining database tag and set db_ver db file access class tag = file(filename, 'rb').read(4) # Auto detect database type for existing vaults if (ver3.db_test_bg_tag(tag)): self.db_ver = ver3 elif (ver4.db_test_bg_tag(tag)): self.db_ver = ver4 else: raise self.VaultVersionError("Not a PasswordSafe V3 and V4 compatible file") if self.db_format != self.db_ver.db_format: if self.db_format == "auto": self.db_format = self.db_ver.db_format else: print("Database version missmatch I was asked to open database with version %s and it's a %s version" % (self.db_format, self.db_ver.db_format)) sys.exit(1) # Open password database self.db_ver.db_open(filename) # Read database header to Vault class fill all required fields self.db_ver.db_read_header(password, self) # Get Stretched master password from db stretched_password = self.db_ver.db_get_stretched_passwd(self, password) # P': the stretched key my_sha_ps = hashlib.sha256(stretched_password).digest() if (self.f_sha_ps != my_sha_ps): raise self.BadPasswordError("Wrong password") cipher = TwofishECB(stretched_password) key_k = cipher.decrypt(self.f_b1) + cipher.decrypt(self.f_b2) key_l = cipher.decrypt(self.f_b3) + cipher.decrypt(self.f_b4) hmac_checker = HMAC(key_l, "", hashlib.sha256) cipher = TwofishCBC(key_k, self.f_iv) # read header while (True): field = self._read_field_tlv(cipher) if not field: break if field.raw_type == 0xff: break self.header.add_raw_field(field) hmac_checker.update(field.raw_value) # read fields current_record = self.Record() while (True): field = self._read_field_tlv(cipher) if not field: break if field.raw_type == 0xff: self.records.append(current_record) current_record = self.Record() else: hmac_checker.update(field.raw_value) current_record.add_raw_field(field) # read HMAC self.f_hmac = self.db_ver.db_read_data(32) # HMAC: used to verify Vault's integrity my_hmac = hmac_checker.digest() if (self.f_hmac != my_hmac): raise self.VaultFormatError("File integrity check failed") self.records.sort() self.db_ver.db_close()
def write_to_file(self, filename, password): """ Store contents of this Vault into a file. """ assert type(password) != str _last_save = struct.pack("<L", int(time.time())) self.header.raw_fields[0x04] = self.Field(0x04, len(_last_save), _last_save) _what_saved = prog_name+" "+prog_version.encode("utf_8", "replace") self.header.raw_fields[0x06] = self.Field(0x06, len(_what_saved), _what_saved) # write to temporary file first (osfilehandle, tmpfilename) = tempfile.mkstemp('.part', os.path.basename(filename) + ".", os.path.dirname(filename), text=False) self.db_ver.db_open(tmpfilename, 'wb') # f_sha_ps should be already defined, why we want to regen it here. stretched_password = self.db_ver.db_get_stretched_passwd(self, password) self.f_sha_ps = hashlib.sha256(stretched_password).digest() self.db_ver.db_write_header(self, password) cipher = TwofishECB(stretched_password) key_k = cipher.decrypt(self.f_b1) + cipher.decrypt(self.f_b2) key_l = cipher.decrypt(self.f_b3) + cipher.decrypt(self.f_b4) hmac_checker = HMAC(key_l, "", hashlib.sha256) cipher = TwofishCBC(key_k, self.f_iv) end_of_record = self.Field(0xff, 0, "") for field in list(self.header.raw_fields.values()): self._write_field_tlv(cipher, field) hmac_checker.update(field.raw_value) self._write_field_tlv(cipher, end_of_record) hmac_checker.update(end_of_record.raw_value) for record in self.records: for field in list(record.raw_fields.values()): self._write_field_tlv(cipher, field) hmac_checker.update(field.raw_value) self._write_field_tlv(cipher, end_of_record) hmac_checker.update(end_of_record.raw_value) self.db_ver.db_end_data() self.f_hmac = hmac_checker.digest() self.db_ver.db_write_data(self.f_hmac) self.db_ver.db_close() try: tmpvault = Vault(password, filename=tmpfilename, format=self.db_ver.db_format) except RuntimeError: os.remove(tmpfilename) raise self.VaultFormatError("File integrity check failed") # after writing the temporary file, replace the original file with it try: os.remove(filename) except OSError: pass os.rename(tmpfilename, filename)
# Because we are extending the hashlib module, we need to import all its # fields to suppport the same uses from . import tlshashlib from .compat import compatHMAC try: from hmac import compare_digest __all__ = ["new", "compare_digest", "HMAC"] except ImportError: __all__ = ["new", "HMAC"] try: from hmac import HMAC, new # if we can calculate HMAC on MD5, then use the built-in HMAC # implementation _val = HMAC(b'some key', b'msg', 'md5') _val.digest() del _val except Exception: # fallback only when MD5 doesn't work class HMAC(object): """Hacked version of HMAC that works in FIPS mode even with MD5.""" def __init__(self, key, msg=None, digestmod=None): """ Initialise the HMAC and hash first portion of data. msg: data to hash digestmod: name of hash or object that be used as a hash and be cloned """ self.key = key if digestmod is None: digestmod = 'md5'
def _read_from_file(self, filename, password): """ Initialize all class members by loading the contents of a Vault stored in the given file. """ assert type(password) != unicode filehandle = file(filename, "rb") # read boilerplate self.f_tag = filehandle.read(4) # TAG: magic tag if self.f_tag != "PWS3": raise self.VaultVersionError("Not a PasswordSafe V3 file") self.f_salt = filehandle.read(32) # SALT: SHA-256 salt self.f_iter = struct.unpack("<L", filehandle.read(4))[0] # ITER: SHA-256 keystretch iterations stretched_password = self._stretch_password(password, self.f_salt, self.f_iter) # P': the stretched key my_sha_ps = hashlib.sha256(stretched_password).digest() self.f_sha_ps = filehandle.read(32) # H(P'): SHA-256 hash of stretched passphrase if self.f_sha_ps != my_sha_ps: raise self.BadPasswordError("Wrong password") self.f_b1 = filehandle.read(16) # B1 self.f_b2 = filehandle.read(16) # B2 self.f_b3 = filehandle.read(16) # B3 self.f_b4 = filehandle.read(16) # B4 cipher = TwofishECB(stretched_password) key_k = cipher.decrypt(self.f_b1) + cipher.decrypt(self.f_b2) key_l = cipher.decrypt(self.f_b3) + cipher.decrypt(self.f_b4) self.f_iv = filehandle.read(16) # IV: initialization vector of Twofish CBC hmac_checker = HMAC(key_l, "", hashlib.sha256) cipher = TwofishCBC(key_k, self.f_iv) # read header while True: field = self._read_field_tlv(filehandle, cipher) if not field: break if field.raw_type == 0xFF: break self.header.add_raw_field(field) hmac_checker.update(field.raw_value) # read fields current_record = self.Record() while True: field = self._read_field_tlv(filehandle, cipher) if not field: break if field.raw_type == 0xFF: self.records.append(current_record) current_record = self.Record() else: hmac_checker.update(field.raw_value) current_record.add_raw_field(field) # read HMAC self.f_hmac = filehandle.read(32) # HMAC: used to verify Vault's integrity my_hmac = hmac_checker.digest() if self.f_hmac != my_hmac: raise self.VaultFormatError("File integrity check failed") self.records.sort() filehandle.close()
def prf(self, key, data): m = HMAC(key, data, digestmod=self.hasher) return m.digest()
def compute(self, key, data): m = HMAC(key, data, digestmod=self.hasher) return m.digest()[:self.hash_size]
def hmac_sha256(secret, msg): hmac = HMAC(secret, msg=msg, digestmod=hashlib.sha256) val = hmac.digest() return val
def write_to_file(self, filename, password): """ Store contents of this Vault into a file. """ assert type(password) != unicode _last_save = struct.pack("<L", int(time.time())) self.header.raw_fields[0x04] = self.Field(0x04, len(_last_save), _last_save) _what_saved = "Loxodo 0.0-git".encode("utf_8", "replace") self.header.raw_fields[0x06] = self.Field(0x06, len(_what_saved), _what_saved) # write to temporary file first (osfilehandle, tmpfilename) = tempfile.mkstemp('.part', os.path.basename(filename) + ".", os.path.dirname(filename), text=False) filehandle = os.fdopen(osfilehandle, "wb") # FIXME: choose new SALT, B1-B4, IV values on each file write? Conflicting Specs! # write boilerplate filehandle.write(self.f_tag) filehandle.write(self.f_salt) filehandle.write(struct.pack("<L", self.f_iter)) stretched_password = self._stretch_password(password, self.f_salt, self.f_iter) self.f_sha_ps = hashlib.sha256(stretched_password).digest() filehandle.write(self.f_sha_ps) filehandle.write(self.f_b1) filehandle.write(self.f_b2) filehandle.write(self.f_b3) filehandle.write(self.f_b4) cipher = TwofishECB(stretched_password) key_k = cipher.decrypt(self.f_b1) + cipher.decrypt(self.f_b2) key_l = cipher.decrypt(self.f_b3) + cipher.decrypt(self.f_b4) filehandle.write(self.f_iv) hmac_checker = HMAC(key_l, "", hashlib.sha256) cipher = TwofishCBC(key_k, self.f_iv) end_of_record = self.Field(0xff, 0, "") for field in self.header.raw_fields.values(): self._write_field_tlv(filehandle, cipher, field) hmac_checker.update(field.raw_value) self._write_field_tlv(filehandle, cipher, end_of_record) hmac_checker.update(end_of_record.raw_value) for record in self.records: for field in record.raw_fields.values(): self._write_field_tlv(filehandle, cipher, field) hmac_checker.update(field.raw_value) self._write_field_tlv(filehandle, cipher, end_of_record) hmac_checker.update(end_of_record.raw_value) self._write_field_tlv(filehandle, cipher, None) self.f_hmac = hmac_checker.digest() filehandle.write(self.f_hmac) filehandle.close() try: tmpvault = Vault(password, filename=tmpfilename) except RuntimeError: os.remove(tmpfilename) raise self.VaultFormatError("File integrity check failed") # after writing the temporary file, replace the original file with it try: os.remove(filename) except OSError: pass os.rename(tmpfilename, filename)
def _read_from_file(self, filename, password): """ Initialize all class members by loading the contents of a Vault stored in the given file. """ assert type(password) != unicode filehandle = file(filename, 'rb') # read boilerplate self.f_tag = filehandle.read(4) # TAG: magic tag if (self.f_tag != 'PWS3'): raise self.VaultVersionError("Not a PasswordSafe V3 file") self.f_salt = filehandle.read(32) # SALT: SHA-256 salt self.f_iter = struct.unpack( "<L", filehandle.read(4))[0] # ITER: SHA-256 keystretch iterations stretched_password = self._stretch_password( password, self.f_salt, self.f_iter) # P': the stretched key my_sha_ps = hashlib.sha256(stretched_password).digest() self.f_sha_ps = filehandle.read( 32) # H(P'): SHA-256 hash of stretched passphrase if (self.f_sha_ps != my_sha_ps): raise self.BadPasswordError("Wrong password") self.f_b1 = filehandle.read(16) # B1 self.f_b2 = filehandle.read(16) # B2 self.f_b3 = filehandle.read(16) # B3 self.f_b4 = filehandle.read(16) # B4 cipher = TwofishECB(stretched_password) key_k = cipher.decrypt(self.f_b1) + cipher.decrypt(self.f_b2) key_l = cipher.decrypt(self.f_b3) + cipher.decrypt(self.f_b4) self.f_iv = filehandle.read( 16) # IV: initialization vector of Twofish CBC hmac_checker = HMAC(key_l, "", hashlib.sha256) cipher = TwofishCBC(key_k, self.f_iv) # read header while (True): field = self._read_field_tlv(filehandle, cipher) if not field: break if field.raw_type == 0xff: break self.header.add_raw_field(field) hmac_checker.update(field.raw_value) # read fields current_record = self.Record() while (True): field = self._read_field_tlv(filehandle, cipher) if not field: break if field.raw_type == 0xff: self.records.append(current_record) current_record = self.Record() else: hmac_checker.update(field.raw_value) current_record.add_raw_field(field) # read HMAC self.f_hmac = filehandle.read( 32) # HMAC: used to verify Vault's integrity my_hmac = hmac_checker.digest() if (self.f_hmac != my_hmac): raise self.VaultFormatError("File integrity check failed") self.records.sort() filehandle.close()
def write_to_file(self, filename, password): """ Store contents of this Vault into a file. """ assert type(password) != unicode _last_save = struct.pack("<L", int(time.time())) self.header.raw_fields[0x04] = self.Field(0x04, len(_last_save), _last_save) _what_saved = "Loxodo 0.0-git".encode("utf_8", "replace") self.header.raw_fields[0x06] = self.Field(0x06, len(_what_saved), _what_saved) # write to temporary file first (osfilehandle, tmpfilename) = tempfile.mkstemp( ".part", os.path.basename(filename) + ".", os.path.dirname(filename), text=False ) filehandle = os.fdopen(osfilehandle, "wb") # FIXME: choose new SALT, B1-B4, IV values on each file write? Conflicting Specs! # write boilerplate filehandle.write(self.f_tag) filehandle.write(self.f_salt) filehandle.write(struct.pack("<L", self.f_iter)) stretched_password = self._stretch_password(password, self.f_salt, self.f_iter) self.f_sha_ps = hashlib.sha256(stretched_password).digest() filehandle.write(self.f_sha_ps) filehandle.write(self.f_b1) filehandle.write(self.f_b2) filehandle.write(self.f_b3) filehandle.write(self.f_b4) cipher = TwofishECB(stretched_password) key_k = cipher.decrypt(self.f_b1) + cipher.decrypt(self.f_b2) key_l = cipher.decrypt(self.f_b3) + cipher.decrypt(self.f_b4) filehandle.write(self.f_iv) hmac_checker = HMAC(key_l, "", hashlib.sha256) cipher = TwofishCBC(key_k, self.f_iv) end_of_record = self.Field(0xFF, 0, "") for field in self.header.raw_fields.values(): self._write_field_tlv(filehandle, cipher, field) hmac_checker.update(field.raw_value) self._write_field_tlv(filehandle, cipher, end_of_record) hmac_checker.update(end_of_record.raw_value) for record in self.records: for field in record.raw_fields.values(): self._write_field_tlv(filehandle, cipher, field) hmac_checker.update(field.raw_value) self._write_field_tlv(filehandle, cipher, end_of_record) hmac_checker.update(end_of_record.raw_value) self._write_field_tlv(filehandle, cipher, None) self.f_hmac = hmac_checker.digest() filehandle.write(self.f_hmac) filehandle.close() try: tmpvault = Vault(password, filename=tmpfilename) except RuntimeError: os.remove(tmpfilename) raise self.VaultFormatError("File integrity check failed") # after writing the temporary file, replace the original file with it try: os.remove(filename) except OSError: pass os.rename(tmpfilename, filename)
def get_credential(secret_key, sign_string, algorithm_name): algorithm = getattr(hashlib, algorithm_name.lower()) hm = HMAC(secret_key.encode(), sign_string.encode(), algorithm) return b64encode(hm.digest())