def encrypt(self, plaintext): if self.state['ratchet_flag']: self.state['DHRs_priv'], self.state['DHRs'] = self.genKey() self.state['HKs'] = self.state['NHKs'] self.state['RK'] = hashlib.sha256(self.state['RK'] + self.genDH(self.state['DHRs_priv'], self.state['DHRr'])).digest() if self.mode: self.state['NHKs'] = pbkdf2(self.state['RK'], b'\x03', 10, prf='hmac-sha256') self.state['CKs'] = pbkdf2(self.state['RK'], b'\x05', 10, prf='hmac-sha256') else: self.state['NHKs'] = pbkdf2(self.state['RK'], b'\x04', 10, prf='hmac-sha256') self.state['CKs'] = pbkdf2(self.state['RK'], b'\x06', 10, prf='hmac-sha256') self.state['PNs'] = self.state['Ns'] self.state['Ns'] = 0 self.state['ratchet_flag'] = False mk = hashlib.sha256(self.state['CKs'] + '0').digest() msg1 = self.enc(self.state['HKs'], str(self.state['Ns']).zfill(3) + str(self.state['PNs']).zfill(3) + self.state['DHRs']) msg2 = self.enc(mk, plaintext) pad_length = 106 - len(msg1) pad = os.urandom(pad_length - 1) + chr(pad_length) msg = msg1 + pad + msg2 #url = 'https://lab3key.herokuapp.com/messages' #payload = {'message':{'source': self.state['name'], 'destination': self.state['other_name'], 'isSMP': False, 'typeSMP': 0, 'payload': msg}} #headers = {'content-type': 'application/json'} #response = requests.post(url, data=json.dumps(payload), headers=headers) #print response.status_code #print response.json() self.state['Ns'] += 1 self.state['CKs'] = hashlib.sha256(self.state['CKs'] + '1').digest() return msg
def encrypt(self, plaintext): if self.state['ratchet_flag']: self.state['DHRs_priv'], self.state['DHRs'] = self.genKey() self.state['HKs'] = self.state['NHKs'] self.state['RK'] = sha256(self.state['RK'] + self.gen_dh( self.state['DHRs_priv'], self.state['DHRr'])).digest() if self.mode: self.state['NHKs'] = pbkdf2(self.state['RK'], b'\x03', 10, prf='hmac-sha256') self.state['CKs'] = pbkdf2(self.state['RK'], b'\x05', 10, prf='hmac-sha256') else: self.state['NHKs'] = pbkdf2(self.state['RK'], b'\x04', 10, prf='hmac-sha256') self.state['CKs'] = pbkdf2(self.state['RK'], b'\x06', 10, prf='hmac-sha256') self.state['PNs'] = self.state['Ns'] self.state['Ns'] = 0 self.state['ratchet_flag'] = False mk = sha256(self.state['CKs'] + '0').digest() msg1 = self.enc(self.state['HKs'], str(self.state['Ns']).zfill(3) + str(self.state['PNs']).zfill(3) + self.state['DHRs']) msg2 = self.enc(mk, plaintext) pad_length = 106 - len(msg1) pad = os.urandom(pad_length - 1) + chr(pad_length) msg = msg1 + pad + msg2 self.state['Ns'] += 1 self.state['CKs'] = sha256(self.state['CKs'] + '1').digest() return msg
def decrypt(self): # load database with open(self.desafe_filename, 'r') as f: magic = self.__get_short(f) sver = self.__get_byte(f) salt = self.__get_array(f) skey = pbkdf2.pbkdf2(self.password, salt, 10000, 32) iv = self.__get_array(f) cipher = AES.new(skey, AES.MODE_CBC, iv) salt2 = self.__get_array(f) block = self.__get_array(f) decr = cipher.decrypt(block) sub_fd = StringIO.StringIO(decr) iv2 = self.__get_array(sub_fd) pass2 = self.__get_array(sub_fd) check = self.__get_array(sub_fd) skey2 = pbkdf2.pbkdf2(pass2, salt2, 1000, 32) cipher = AES.new(pass2, AES.MODE_CBC, iv2) data = cipher.decrypt(f.read()) decompressor = zlib.decompressobj() return decompressor.decompress(data) + decompressor.flush()
def initState(self, group_name, identityKeys, handshakeKeys, ratchetKeys): """ Here group_name is the group name, identityKeys, handshakeKeys, and ratchetKeys are dictionaries with key:value pairs equal to the participant index number and the Key value. """ mkey = self.initBD(identityKeys, handshakeKeys, ratchetKeys) del self.bd RK = pbkdf2(mkey, b'\x00', 10, prf='hmac-sha256') MK = pbkdf2(mkey, b'\x01', 10, prf='hmac-sha256') v = pbkdf2(mkey, b'\x02', 10, prf='hmac-sha256') self.state = \ { 'group_name': self.group_name, 'my_index': self.my_index, 'RK': RK, 'MK': MK, 'initpubR' : deepcopy(ratchetKeys), 'initr' : deepcopy(self.ratchetKey), 'R' : ratchetKeys, 'v' : v, 'digest' : '\x00' * 32 }
def decrypt(self, msg): pad = msg[105:106] pad_length = ord(pad) msg1 = msg[:106 - pad_length] body = self.trySkippedMK(msg, pad_length, self.state['name'], self.state['other_name']) if body and body != '': return body header = None if self.state['HKr']: header = self.dec(self.state['HKr'], msg1) if header and header != '': Np = int(header[:3]) CKp, mk = self.stageSkippedMK(self.state['HKr'], self.state['Nr'], Np, self.state['CKr']) body = self.dec(mk, msg[106:]) if not body or body == '': raise (Axolotl_exception('Undecipherable message')) else: header = self.dec(self.state['NHKr'], msg1) if self.state['ratchet_flag'] or not header or header == '': raise (Axolotl_exception('Undecipherable message')) Np = int(header[:3]) PNp = int(header[3:6]) DHRp = header[6:] if self.state['CKr']: self.stageSkippedMK(self.state['HKr'], self.state['Nr'], PNp, self.state['CKr']) HKp = self.state['NHKr'] RKp = sha256( self.state['RK'] + self.gen_dh(self.state['DHRs_priv'], DHRp)).digest() if self.mode: NHKp = pbkdf2(RKp, b'\x04', 10, prf='hmac-sha256') CKp = pbkdf2(RKp, b'\x06', 10, prf='hmac-sha256') else: NHKp = pbkdf2(RKp, b'\x03', 10, prf='hmac-sha256') CKp = pbkdf2(RKp, b'\x05', 10, prf='hmac-sha256') CKp, mk = self.stageSkippedMK(HKp, 0, Np, CKp) body = self.dec(mk, msg[106:]) if not body or body == '': raise (Axolotl_exception('Undecipherable message')) self.state['RK'] = RKp self.state['HKr'] = HKp self.state['NHKr'] = NHKp self.state['DHRr'] = DHRp self.state['DHRs_priv'] = None self.state['DHRs'] = None self.state['ratchet_flag'] = True self.commit_skipped_mk() self.state['Nr'] = Np + 1 self.state['CKr'] = CKp return body
def generate_symmetric_key(self, server_component, client_component, options=None): """ Generate a composite key from a server and client component using a PBKDF2-based scheme. :param server_component: The component usually generated by privacyIDEA :type server_component: hex string :param client_component: The component usually generated by the client (e.g. smartphone) :type client_component: hex string :param options: :return: the new generated key as hex string """ # As /token/init has already been called before, self.hashlib # is already set. keysize = keylen[self.hashlib] rounds = int(self.get_tokeninfo('2step_difficulty')) decoded_client_component = binascii.unhexlify(client_component) expected_client_size = int(self.get_tokeninfo('2step_clientsize')) if expected_client_size != len(decoded_client_component): raise ParameterError('Client Secret Size is expected to be {}, but is {}'.format( expected_client_size, len(decoded_client_component) )) # Based on the two components, we generate a symmetric key using PBKDF2 # We pass the hex-encoded server component as the password and the # client component as the salt. secret = pbkdf2(server_component.lower(), decoded_client_component, rounds, keysize) return binascii.hexlify(secret)
def test_custom_prf(self): """test custom prf function""" from passlib.utils.pbkdf2 import pbkdf2 def prf(key, msg): return hashlib.md5(key+msg+b('fooey')).digest() result = pbkdf2(b('secret'), b('salt'), 1000, 20, prf) self.assertEqual(result, hb('5fe7ce9f7e379d3f65cbc66ba8aa6440474a6849'))
def plaintext_login(self, username, password_plain, **kwargs): password = STRING(binascii.hexlify(pbkdf2(password_plain.encode(), PASSWORD_PBKDF2_HMAC_SHA256_SALT, 10000, keylen=32, prf=str('hmac-sha256')))) return self.user_login(username, password, **kwargs)
def warp(passphrase, salt=""): s1 = scrypt.hash(passphrase + "\x01", salt+"\x01", N=2**18, r=8, p=1, buflen=32) s2 = pbkdf2(passphrase + "\x02", salt=salt+"\x02", keylen=32, rounds=2**16, prf="hmac-sha256") key = binascii.hexlify(xor(s1, s2)) return key, bitcoin.pubtoaddr(bitcoin.privtopub(key))
def add_user(config_uri, username, password_plain, title="default", desc="", flags=0, cellphone="", email="", user_type=USER_TYPE_NORMAL): config = configparser.ConfigParser() config.read(config_uri) settings = dict(config.items("alembic")) engine = engine_from_config(settings, 'sqlalchemy.') if is_str(password_plain): password_plain = password_plain.encode() password_hex = STRING(binascii.hexlify(pbkdf2(bytes(password_plain), PASSWORD_PBKDF2_HMAC_SHA256_SALT, 10000, keylen=32, prf=str('hmac-sha256')))) dao_context_mngr = AlchemyDaoContextMngr(engine) user_dao = SAUserDao(dao_context_mngr) user_mngr = UserManager(user_dao=user_dao, project_dao=None, dao_context_mngr=dao_context_mngr) user_mngr.add_user(username=username, password=password_hex, title=title, desc=desc, flags=flags, cellphone=cellphone, email=email, user_type=user_type)
def generate_psk(instance): passphrase = str(instance.parent.passphrase.text) ssid = str(instance.parent.ssid.text) encoded = pbkdf2.pbkdf2(str.encode(passphrase), str.encode(ssid), 4096, 32) instance.parent.psk.text = binascii.hexlify(encoded).decode( "utf-8")
def decrypt_secret(b64str, pincode): # split the secret into components try: (scheme, salt, ciphertext) = b64str.split('$') salt = base64.b64decode(salt) ciphertext = base64.b64decode(ciphertext) except (ValueError, TypeError): raise totpcgi.UserSecretError('Failed to parse encrypted secret') key = pbkdf2(pincode, salt, KDF_ITER, KEY_SIZE * 2, prf='hmac-sha256') aes_key = key[:KEY_SIZE] hmac_key = key[KEY_SIZE:] sig_size = hashlib.sha256().digest_size sig = ciphertext[-sig_size:] data = ciphertext[:-sig_size] # verify hmac sig first if hmac.new(hmac_key, data, hashlib.sha256).digest() != sig: raise totpcgi.UserSecretError('Failed to verify hmac!') iv_bytes = data[:AES_BLOCK_SIZE] data = data[AES_BLOCK_SIZE:] cypher = AES.new(aes_key, AES.MODE_CBC, iv_bytes) data = cypher.decrypt(data) secret = data[:-ord(data[-1])] logger.debug('Decryption successful') return secret
def resyncSend(self, sock, SLOTTIME): stime = float(SLOTTIME)/4.0 grp = float(SLOTTIME * self.group_size) my = float(SLOTTIME * self.state['my_index']) while abs((time() % grp) - my) >= stime: sleep(0.01 * SLOTTIME) if not self.resync_required: return 'Resync send message aborted' vnew, pVnew = self.genKey() rnew, pRnew = self.genKey() msg1 = self.enc(self.state['v'], '\x00' + str(self.state['my_index']).zfill(3) + vnew + pRnew) mac = hmac.new(self.state['v'], msg1, hashlib.sha256).digest() v = hashlib.sha256(self.state['v'] + vnew).digest() self.state['initr'] = rnew self.state['initpubR'][self.state['my_index']] = pRnew DHR = '' for i in range(len(self.state['R'])): DHR = DHR + self.state['initpubR'][i] DHR = hashlib.sha256(DHR).digest() RK = hashlib.sha256(v + self.genDH(v, DHR)).digest() MK = pbkdf2(RK, b'\x01', 10, prf='hmac-sha256') if self.resync_required: self.resync_required = False self.ratchetKey = deepcopy(self.state['initr']) self.state['R'] = deepcopy(self.state['initpubR']) self.state['v'] = v self.state['RK'] = RK self.state['MK'] = MK self.state['digest'] = '\x00' * 32 sock.send('999' + msg1 + mac + 'EOP') return 'Resync sent' return 'Resync send message aborted'
def derive_digest(cls, password, salt, rounds, alg): """helper to create SaltedPassword digest for SCRAM. This performs the step in the SCRAM protocol described as:: SaltedPassword := Hi(Normalize(password), salt, i) :type password: unicode or utf-8 bytes :arg password: password to run through digest :type salt: bytes :arg salt: raw salt data :type rounds: int :arg rounds: number of iterations. :type alg: str :arg alg: name of digest to use (e.g. ``"sha-1"``). :returns: raw bytes of ``SaltedPassword`` """ if isinstance(password, bytes): password = password.decode("utf-8") password = saslprep(password).encode("utf-8") if not isinstance(salt, bytes): raise TypeError("salt must be bytes") if rounds < 1: raise ValueError("rounds must be >= 1") alg = norm_hash_name(alg, "hashlib") return pbkdf2(password, salt, rounds, None, "hmac-" + alg)
def check(secret64, salt64, key): try: secret = b64decode(secret64) salt = b64decode(salt64) except TypeError: raise ValueError("Unable to base64 decode") return pbkdf2(key, salt, 1000) == secret
def decrypt_secret(b64str, pincode): # split the secret into components try: (scheme, salt, ciphertext) = b64str.split('$') salt = base64.b64decode(salt) ciphertext = base64.b64decode(ciphertext) except (ValueError, TypeError): raise totpcgi.UserSecretError('Failed to parse encrypted secret') key = pbkdf2(pincode, salt, KDF_ITER, KEY_SIZE*2, prf='hmac-sha256') aes_key = key[:KEY_SIZE] hmac_key = key[KEY_SIZE:] sig_size = hashlib.sha256().digest_size sig = ciphertext[-sig_size:] data = ciphertext[:-sig_size] # verify hmac sig first if hmac.new(hmac_key, data, hashlib.sha256).digest() != sig: raise totpcgi.UserSecretError('Failed to verify hmac!') iv_bytes = data[:AES_BLOCK_SIZE] data = data[AES_BLOCK_SIZE:] cypher = AES.new(aes_key, AES.MODE_CBC, iv_bytes) data = cypher.decrypt(data) secret = data[:-ord(data[-1])] logger.debug('Decryption successful') return secret
def derive_digest(cls, password, salt, rounds, alg): """helper to create SaltedPassword digest for SCRAM. This performs the step in the SCRAM protocol described as:: SaltedPassword := Hi(Normalize(password), salt, i) :type password: unicode or utf-8 bytes :arg password: password to run through digest :type salt: bytes :arg salt: raw salt data :type rounds: int :arg rounds: number of iterations. :type alg: str :arg alg: name of digest to use (e.g. ``"sha-1"``). :returns: raw bytes of ``SaltedPassword`` """ if isinstance(password, bytes): password = password.decode("utf-8") password = saslprep(password).encode("utf-8") if not isinstance(salt, bytes): raise TypeError("salt must be bytes") if rounds < 1: raise ValueError("rounds must be >= 1") alg = norm_hash_name(alg, "hashlib") return pbkdf2(password, salt, rounds, None, "hmac-" + alg)
def encrypt_secret(data, pincode): salt = os.urandom(SALT_SIZE) # derive a twice-long key from pincode key = pbkdf2(pincode, salt, KDF_ITER, KEY_SIZE*2, prf='hmac-sha256') # split the key in two, one used for AES, another for HMAC aes_key = key[:KEY_SIZE] hmac_key = key[KEY_SIZE:] pad = AES_BLOCK_SIZE - len(data) % AES_BLOCK_SIZE data = data + pad * chr(pad) iv_bytes = os.urandom(AES_BLOCK_SIZE) cypher = AES.new(aes_key, AES.MODE_CBC, iv_bytes) data = iv_bytes + cypher.encrypt(data) sig = hmac.new(hmac_key, data, hashlib.sha256).digest() # jab it all together in a base64-encrypted format b64str = ('aes256+hmac256$' + base64.b64encode(salt).replace('\n', '') + '$' + base64.b64encode(data+sig).replace('\n', '')) logger.debug('Encrypted secret: %s' % b64str) return b64str
def generate_symmetric_key(self, server_component, client_component, options=None): """ Generate a composite key from a server and client component using a PBKDF2-based scheme. :param server_component: The component usually generated by privacyIDEA :type server_component: hex string :param client_component: The component usually generated by the client (e.g. smartphone) :type client_component: hex string :param options: :return: the new generated key as hex string :rtype: str """ # As /token/init has already been called before, self.hashlib # is already set. keysize = keylen[self.hashlib] rounds = int(self.get_tokeninfo('2step_difficulty')) decoded_client_component = binascii.unhexlify(client_component) expected_client_size = int(self.get_tokeninfo('2step_clientsize')) if expected_client_size != len(decoded_client_component): raise ParameterError('Client Secret Size is expected to be {}, but is {}'.format( expected_client_size, len(decoded_client_component) )) # Based on the two components, we generate a symmetric key using PBKDF2 # We pass the hex-encoded server component as the password and the # client component as the salt. secret = pbkdf2(server_component.lower(), decoded_client_component, rounds, keysize) return hexlify_and_unicode(secret)
def read_sic_db(filename, password): """Read the database and return the XML content.""" with open(filename, 'rb') as db_file: db_file.seek(3) # skip magic + version # Get salt and iv salt = __get_array(db_file) init_vector = __get_array(db_file) __skip_array(db_file) # skip salt 2 # decrypt iv and password block skey = pbkdf2.pbkdf2(password, salt, 10000, 32) cipher = AES.new(skey, AES.MODE_CBC, init_vector) iv_pw_block = cipher.decrypt(__get_array(db_file)) # extract iv and password from block byte_buffer = io.BytesIO(iv_pw_block) iv2 = __get_array(byte_buffer) pass2 = __get_array(byte_buffer) __skip_array(byte_buffer) # skip check # decrypt data cipher = AES.new(pass2, AES.MODE_CBC, iv2) data = cipher.decrypt(db_file.read()) # decompress data decompressor = zlib.decompressobj() return decompressor.decompress(data) + decompressor.flush()
def test_known(self): """test reference vectors""" from passlib.utils.pbkdf2 import pbkdf2 for row in self.pbkdf2_test_vectors: correct, secret, salt, rounds, keylen = row[:5] prf = row[5] if len(row) == 6 else "hmac-sha1" result = pbkdf2(secret, salt, rounds, keylen, prf) self.assertEqual(result, correct)
def test_known(self): """test reference vectors""" from passlib.utils.pbkdf2 import pbkdf2 for row in self.pbkdf2_test_vectors: correct, secret, salt, rounds, keylen = row[:5] prf = row[5] if len(row) == 6 else "hmac-sha1" result = pbkdf2(secret, salt, rounds, keylen, prf) self.assertEqual(result, correct)
def _pbkdf2(self, passphrase, salt=""): hexlified_key = binascii.hexlify(passphrase) + "02" pbkdf2_key = binascii.unhexlify(hexlified_key) hexlified_salt = binascii.hexlify(salt) + "02" pbkdf2_salt = binascii.unhexlify(hexlified_salt) out = pbkdf2.pbkdf2(secret=pbkdf2_key, salt=pbkdf2_salt, keylen=self.dklen, rounds=self.pbkdf2_count, prf='hmac_sha256') return out
def _calc_checksum(self, secret): if isinstance(secret, unicode): secret = secret.encode("utf-8") hash = pbkdf2(secret, self.salt.encode("ascii"), self.rounds, keylen=None, prf=self._prf) return b64encode(hash).rstrip().decode("ascii")
def check(secret64, salt64, key): try: secret = b64decode(secret64) salt = b64decode(salt64) except TypeError as e: print(str(e)) exit(1) out = pbkdf2(key, salt, 1000) status = (out == secret) if status: addKey(secret64, salt64, key) return status
def decrypt( self, b64_data ): """ Requires b64 data separated by # to decrypt """ # TODO: Verify the data and add a try statement? salt, iv, cipher_text = b64_data.split('#', 3) salt = base64.standard_b64decode(salt) iv = base64.standard_b64decode(iv) cipher_text = base64.standard_b64decode(cipher_text) key = pbkdf2(self.passphrase, salt, ITERATION_COUNT, keylen=KEY_LENGTH) cipher = AES.new(key, AES.MODE_CBC, iv ) return unpad(cipher.decrypt( cipher_text ))
def encrypt( self, raw ): """ Returns the encrypted value encoded in b64 with salt, iv and cipher text separated by #. """ raw = pad(raw) salt = Random.new().read(SALT_LENGTH) iv = Random.new().read(BS) key = pbkdf2(self.passphrase, salt, ITERATION_COUNT, keylen=KEY_LENGTH) cipher = AES.new( key, AES.MODE_CBC, iv ) cipher_text = cipher.encrypt( raw ) return ( '#'.join([base64.standard_b64encode(salt)+'\n', base64.standard_b64encode(iv)+'\n', base64.standard_b64encode(cipher_text)+'\n']) )
def decrypt_profile(ciphertext, passphrase): key = pbkdf2( bytes(passphrase.encode("utf-8")), sha256(bytes(passphrase.encode("utf-8"))).hexdigest().encode("utf-8"), 2056, 32, "hmac-sha256") iv = ciphertext[0:16] decryptor = AES.new(key, AES.MODE_CBC, iv) plaintext = decryptor.decrypt(ciphertext[16:]) try: return plaintext[:-plaintext[-1]].decode("utf-8") except UnicodeDecodeError: raise AssertionError("profile could not be decrypted")
def set_network(self, ssid, psk): # As in wpa passphrase 2.5 hashed_psk_bytes = pbkdf2(psk, ssid, 4096, 32) # Get into the correct format hashed_psk = hashed_psk_bytes.encode("hex") self.ctrl_request("SET_NETWORK 0 ssid {}".format(ssid)) self.ctrl_request("SET_NETWORK 0 psk {}".format(hashed_psk)) self.ctrl_request("ENABLE_NETWORK 0") self.ctrl_request("SAVE") self.ctrl_request("RECONFIGURE")
def test_30_2step_otpkeyformat(self): serial = "2step3" db_token = Token(serial, tokentype="hotp") db_token.save() token = HotpTokenClass(db_token) token.update({ "2stepinit": "1", "2step_clientsize": "12", "hashlib": "sha512", }) self.assertEqual(token.token.rollout_state, "clientwait") self.assertEqual(token.get_tokeninfo("2step_clientsize"), "12") # fetch the server component for later tests server_component = binascii.unhexlify( token.token.get_otpkey().getKey()) # generate a 12-byte client component client_component = b'abcdefghijkl' checksum = hashlib.sha1(client_component).digest()[:4] # wrong checksum self.assertRaisesRegexp( ParameterError, "Incorrect checksum", token.update, { "otpkey": base64.b32encode("\x37" + checksum[1:] + client_component).strip("="), "otpkeyformat": "base32check", }) # construct a secret token.update({ "otpkey": base64.b32encode(checksum + client_component).strip("="), "otpkeyformat": "base32check", # the following values are ignored "2step_serversize": "23", "2step_difficulty": "666666", "2step_clientsize": "13" }) # check the generated secret secret = binascii.unhexlify(token.token.get_otpkey().getKey()) # check the correct lengths self.assertEqual(len(server_component), 64) # because of SHA-512 self.assertEqual(len(client_component), 12) self.assertEqual(len(secret), 64) # because of SHA-512 # check the secret has been generated according to the specification expected_secret = pbkdf2(binascii.hexlify(server_component), client_component, 10000, len(secret)) self.assertEqual(secret, expected_secret) self.assertTrue(token.token.active)
def crackRestrictionsKey(base64Hash, base64Salt): secret = base64.b64decode(base64Hash) salt = base64.b64decode(base64Salt) startTime = time() for i in range(10000): key = "%04d" % (i) out = pbkdf2(key, salt, 1000) if out == secret: print "[+] Passcode: ", key duration = time() - startTime print "[*] %f seconds" % (duration) return key return False
def warp(passphrase, salt=""): s1 = scrypt.hash(passphrase + "\x01", salt + "\x01", N=2**18, r=8, p=1, buflen=32) s2 = pbkdf2(passphrase + "\x02", salt=salt + "\x02", keylen=32, rounds=2**16, prf="hmac-sha256") key = binascii.hexlify(xor(s1, s2)) return key, bitcoin.pubtoaddr(bitcoin.privtopub(key))
def decrypt_profile(ciphertext, passphrase): key = pbkdf2( bytes(passphrase.encode("utf-8")), sha256(bytes(passphrase.encode("utf-8"))).hexdigest().encode("utf-8"), 2056, 32, "hmac-sha256" ) iv = ciphertext[0:16] decryptor = AES.new(key, AES.MODE_CBC, iv) plaintext = decryptor.decrypt(ciphertext[16:]) try: return plaintext[:-plaintext[-1]].decode("utf-8") except UnicodeDecodeError: raise AssertionError("profile could not be decrypted")
def crack(secret64, salt64): print "secret: ", secret64 print "salt: ", salt64 secret = base64.b64decode(secret64) salt = base64.b64decode(salt64) start_t = time() for i in range(10000): key = "%04d" % (i) out = pbkdf2(key, salt, 1000) if out == secret: print "key: ", key duration = time() - start_t print "%f seconds" % (duration) sys.exit(0) print "no exact key"
def raw(cls, secret, user): """encode password using msdcc v2 algorithm :type secret: unicode or utf-8 bytes :arg secret: secret :type user: str :arg user: username to use as salt :returns: returns string of raw bytes """ from passlib.utils.pbkdf2 import pbkdf2 secret = to_unicode(secret, "utf-8", param="secret").encode("utf-16-le") user = to_unicode(user, "utf-8", param="user").lower().encode("utf-16-le") tmp = md4(md4(secret).digest() + user).digest() return pbkdf2(tmp, user, 10240, 16, 'hmac-sha1')
def wpa_passphrase(ssid, password): """ Python implementation of wpa_passphrase linux utility It generates wpa_passphrase for wifi network connection Note: Copied from https://github.com/julianofischer/python-wpa-psk-rawkey-gen/blob/master/rawkey-generator.py Args: ssid (string): network ssid password (string): password Returns: string: generated psk """ psk = pbkdf2.pbkdf2(str.encode(password), str.encode(ssid), 4096, 32) return binascii.hexlify(psk).decode("utf-8")
def test_30_2step_otpkeyformat(self): serial = "2step3" db_token = Token(serial, tokentype="hotp") db_token.save() token = HotpTokenClass(db_token) token.update({ "2stepinit": "1", "2step_clientsize": "12", "hashlib": "sha512", }) self.assertEqual(token.token.rollout_state, "clientwait") self.assertEqual(token.get_tokeninfo("2step_clientsize"), "12") # fetch the server component for later tests server_component = binascii.unhexlify(token.token.get_otpkey().getKey()) # generate a 12-byte client component client_component = b'abcdefghijkl' checksum = hashlib.sha1(client_component).digest()[:4] # wrong checksum self.assertRaisesRegexp( ParameterError, "Incorrect checksum", token.update, { "otpkey": base64.b32encode("\x37" + checksum[1:] + client_component).strip("="), "otpkeyformat": "base32check", }) # construct a secret token.update({ "otpkey": base64.b32encode(checksum + client_component).strip("="), "otpkeyformat": "base32check", # the following values are ignored "2step_serversize": "23", "2step_difficulty": "666666", "2step_clientsize": "13" }) # check the generated secret secret = binascii.unhexlify(token.token.get_otpkey().getKey()) # check the correct lengths self.assertEqual(len(server_component), 64) # because of SHA-512 self.assertEqual(len(client_component), 12) self.assertEqual(len(secret), 64) # because of SHA-512 # check the secret has been generated according to the specification expected_secret = pbkdf2(binascii.hexlify(server_component), client_component, 10000, len(secret)) self.assertEqual(secret, expected_secret) self.assertTrue(token.token.active)
def main(): parser = argparse.ArgumentParser(description='''Use PBKDF2 from Python's passlib to derive a key, given a secret and a salt''') parser.add_argument('secret') parser.add_argument('salt') parser.add_argument('-b', '--begin', help='''define where to start slicing the result (equivalent to result[b:])''', default=0, type=int) parser.add_argument('-e', '--end', help='''define where to stop slicing the result (equivalent to result[:e])''', type=int) parser.add_argument('-f', '--family', help='choose a pseudo-random family', default='sha512', choices=['md5', 'sha1', 'sha256', 'sha512']) parser.add_argument('-r', '--rounds', help='''define the number of rounds to use on the generation (an integer greater than zero)''', default=10000, type=positive_integer) parser.add_argument('-c', '--copy', help='''copy the output to the clipboard by piping it to xclip instead of printing''', action='store_true') args = parser.parse_args() result = b64encode(pbkdf2(args.secret, args.salt, args.rounds, prf='hmac-'+args.family)) if args.end: result = result[args.begin:args.end] else: result = result[args.begin:] if args.copy: copy(result) else: print result
def _pl_salted_sha512_pbkdf2_from_string(strvalue, salt_bin=None, iterations=1000): ''' Create a PBKDF2-SHA512 hash with a 128 byte key length. The standard passlib.hash.pbkdf2_sha512 functions assume a 64 byte key length which does not match OSX's implementation. :param strvalue: The string to derive the hash from :param salt: The (randomly generated) salt :param iterations: The number of iterations, for Mac OS X it's normally between 23000-25000? need to confirm. :return: (binary digest, binary salt, number of iterations used) ''' if salt_bin is None: salt_bin = os.urandom(32) key_length = 128 hmac_sha512, dsize = pbkdf2.get_prf("hmac-sha512") digest_bin = pbkdf2.pbkdf2(strvalue, salt_bin, iterations, key_length, hmac_sha512) return digest_bin, salt_bin, iterations
def test_29_2step_generation_custom(self): serial = "2step2" db_token = Token(serial, tokentype="hotp") db_token.save() token = HotpTokenClass(db_token) token.update({ "2stepinit": "1", "2step_serversize": "40", "2step_difficulty": "12345", "2step_clientsize": "12", "hashlib": "sha512", }) self.assertEqual(token.token.rollout_state, "clientwait") self.assertEqual(token.get_tokeninfo("2step_clientsize"), "12") self.assertEqual(token.get_tokeninfo("2step_difficulty"), "12345") # fetch the server component for later tests server_component = binascii.unhexlify( token.token.get_otpkey().getKey()) # too short self.assertRaises(ParameterError, token.update, {"otpkey": binascii.hexlify("=" * 8)}) # generate a 12-byte client component client_component = b'abcdefghijkl' # construct a secret token.update({ "otpkey": binascii.hexlify(client_component), # the following values are ignored "2step_serversize": "23", "2step_difficulty": "666666", "2step_clientsize": "13" }) # check the generated secret secret = binascii.unhexlify(token.token.get_otpkey().getKey()) # check the correct lengths self.assertEqual(len(server_component), 40) self.assertEqual(len(client_component), 12) self.assertEqual(len(secret), 64) # because of SHA-512 # check the secret has been generated according to the specification expected_secret = pbkdf2(binascii.hexlify(server_component), client_component, 12345, len(secret)) self.assertEqual(secret, expected_secret) self.assertTrue(token.token.active)
def decrypt(self, msg): if hmac.new(self.state['v'], msg[:-32], hashlib.sha256).digest() != msg[-32:]: raise BadHMAC plaintext = self.dec(self.state['MK'], msg[:-32]) if not plaintext or plaintext == '': return self.resyncReceive(msg[:-32]) Pnum = int(plaintext[:3]) otp = hashlib.sha256(self.genDH(self.ratchetKey, self.state['R'][Pnum])).digest() self.state['R'][Pnum] = self.strxor(plaintext[3:35], otp) DHR = self.state['digest'] for i in range(self.group_size): DHR = DHR + self.genDH(self.state['v'], self.state['R'][i]) DHR = hashlib.sha256(DHR).digest() self.state['digest'] = self.strxor(hashlib.sha256(plaintext[35:]).digest(), self.state['digest']) self.state['RK'] = hashlib.sha256(self.state['RK'] + self.genDH(self.state['v'], DHR)).digest() self.state['MK'] = pbkdf2(self.state['RK'], b'\x01', 10, prf='hmac-sha256') return plaintext[35:]
def test_29_2step_generation_custom(self): serial = "2step2" db_token = Token(serial, tokentype="hotp") db_token.save() token = HotpTokenClass(db_token) token.update({ "2stepinit": "1", "2step_serversize": "40", "2step_difficulty": "12345", "2step_clientsize": "12", "hashlib": "sha512", }) self.assertEqual(token.token.rollout_state, "clientwait") self.assertEqual(token.get_tokeninfo("2step_clientsize"), "12") self.assertEqual(token.get_tokeninfo("2step_difficulty"), "12345") # fetch the server component for later tests server_component = binascii.unhexlify(token.token.get_otpkey().getKey()) # too short self.assertRaises(ParameterError, token.update, { "otpkey": binascii.hexlify("="*8) }) # generate a 12-byte client component client_component = b'abcdefghijkl' # construct a secret token.update({ "otpkey": binascii.hexlify(client_component), # the following values are ignored "2step_serversize": "23", "2step_difficulty": "666666", "2step_clientsize": "13" }) # check the generated secret secret = binascii.unhexlify(token.token.get_otpkey().getKey()) # check the correct lengths self.assertEqual(len(server_component), 40) self.assertEqual(len(client_component), 12) self.assertEqual(len(secret), 64) # because of SHA-512 # check the secret has been generated according to the specification expected_secret = pbkdf2(binascii.hexlify(server_component), client_component, 12345, len(secret)) self.assertEqual(secret, expected_secret) self.assertTrue(token.token.active)
def derive_key(xml, password): """ Derive the encryption key from the password with the parameters given in the XML soup. :param xml: The XML :param password: the password :return: The derived key, hexlified """ if not password: raise ImportException("The XML KeyContainer specifies a derived " "encryption key, but no password given!") keymeth = xml.keycontainer.encryptionkey.derivedkey.keyderivationmethod derivation_algo = keymeth["algorithm"].split("#")[-1] if derivation_algo.lower() != "pbkdf2": raise ImportException("We only support PBKDF2 as Key derivation " "function!") salt = keymeth.find("salt").text.strip() keylength = keymeth.find("keylength").text.strip() rounds = keymeth.find("iterationcount").text.strip() r = pbkdf2(to_utf8(password), base64.b64decode(salt), int(rounds), int(keylength)) return binascii.hexlify(r)
def test_28_2step_generation_default(self): serial = "2step" db_token = Token(serial, tokentype="hotp") db_token.save() token = HotpTokenClass(db_token) token.update({"2stepinit": "1"}) # fetch the server component for later tests server_component = binascii.unhexlify(token.token.get_otpkey().getKey()) # generate a 8-byte client component client_component = b'abcdefgh' # construct a secret token.update({"otpkey": binascii.hexlify(client_component)}) # check the generated secret secret = binascii.unhexlify(token.token.get_otpkey().getKey()) # check the correct lengths self.assertEqual(len(server_component), 20) self.assertEqual(len(client_component), 8) self.assertEqual(len(secret), 20) # check the secret has been generated according to the specification expected_secret = pbkdf2(binascii.hexlify(server_component), client_component, 10000, 20) self.assertEqual(secret, expected_secret)
def test_28_2step_generation_default(self): serial = "2step" db_token = Token(serial, tokentype="hotp") db_token.save() token = HotpTokenClass(db_token) token.update({"2stepinit": "1"}) # fetch the server component for later tests server_component = binascii.unhexlify(token.token.get_otpkey().getKey()) # generate a 8-byte client component client_component = b'abcdefgh' # construct a secret token.update({"otpkey": binascii.hexlify(client_component)}) # check the generated secret secret = binascii.unhexlify(token.token.get_otpkey().getKey()) # check the correct lengths self.assertEqual(len(server_component), 20) self.assertEqual(len(client_component), 8) self.assertEqual(len(secret), 20) # check the secret has been generated according to the specification expected_secret = pbkdf2(binascii.hexlify(server_component), client_component, 10000, 20) self.assertEqual(secret, expected_secret)
def add_user(config_uri, username, password_plain, title="default", desc="", flags=0, cellphone="", email="", user_type=User.USER_TYPE_NORMAL): config = configparser.ConfigParser() config.read(config_uri) settings = dict(config.items("alembic")) engine = engine_from_config(settings, 'sqlalchemy.') if is_str(password_plain): password_plain = password_plain.encode() password_hex = STRING( binascii.hexlify( pbkdf2(password_plain, PASSWORD_PBKDF2_HMAC_SHA256_SALT, 100000, keylen=32, prf=str('hmac-sha256')))) dao_context_mngr = AlchemyDaoContextMngr(engine) user_dao = SAUserDao(dao_context_mngr) user_mngr = UserManager(user_dao=user_dao, project_dao=None, dao_context_mngr=dao_context_mngr) user_mngr.add_user(username=username, password=password_hex, title=title, desc=desc, flags=flags, cellphone=cellphone, email=email, user_type=user_type)
def _pl_salted_sha512_pbkdf2_from_string(strvalue, salt_bin=None, iterations=1000): ''' Create a PBKDF2-SHA512 hash with a 128 byte key length. The standard passlib.hash.pbkdf2_sha512 functions assume a 64 byte key length which does not match OSX's implementation. :param strvalue: The string to derive the hash from :param salt: The (randomly generated) salt :param iterations: The number of iterations, for Mac OS X it's normally between 23000-25000? need to confirm. :return: (binary digest, binary salt, number of iterations used) ''' if salt_bin is None: salt_bin = os.urandom(32) key_length = 128 hmac_sha512, dsize = pbkdf2.get_prf("hmac-sha512") digest_bin = pbkdf2.pbkdf2(strvalue, salt_bin, iterations, key_length, hmac_sha512) return digest_bin, salt_bin, iterations
def getPsk(sed): ''' Read the PSK to use from the file system. The generated PSK is stored in a file and later read from the file. For the real life use case the file needs to be replaced with a key manager since storing the PSK in a file is not a safe practice. Parameters: sed - SED data structure of the drive ''' try: with open("psk.txt", 'rb') as f: psk = f.read() except IOError: psk = pbkdf2(hex(sed.wwn) + '7i92G*dp#' + sed.mSID, sed.random(), 6996, keylen=64) if psk is None: return None with open("psk.txt", "wb") as psk_file: psk_file.write(psk) psk_file.close() return psk
def encrypt(self, plaintext): rnew, Rnew = self.genKey() messages = {} for i in range(self.group_size): if i != self.state['my_index']: otp = hashlib.sha256(self.genDH(self.ratchetKey, self.state['R'][i])).digest() encrypted_Rnew = self.strxor(Rnew, otp) msg = self.enc(self.state['MK'], str(self.state['my_index']).zfill(3) + encrypted_Rnew + plaintext) mac = hmac.new(self.state['v'], msg, hashlib.sha256).digest() # not part of protocol messages[i] = str(i).zfill(3) + msg + mac self.ratchetKey = rnew self.state['R'][self.state['my_index']] = Rnew DHR = self.state['digest'] for i in range(self.group_size): DHR = DHR + self.genDH(self.state['v'], self.state['R'][i]) DHR = hashlib.sha256(DHR).digest() self.state['digest'] = self.strxor(self.state['digest'], hashlib.sha256(plaintext).digest()) self.state['RK'] = hashlib.sha256(self.state['RK'] + self.genDH(self.state['v'], DHR)).digest() self.state['MK'] = pbkdf2(self.state['RK'], b'\x01', 10, prf='hmac-sha256') return messages
def resyncReceive(self, ciphertext): try: plaintext = self.dec(self.state['v'], ciphertext) except (DecodeError, ValueError): raise BummerUndecryptable if plaintext[:1] != '\x00' or len(plaintext) != 68 or ciphertext is None: raise BadDIGEST else: self.resync_required = False self.state['v'] = hashlib.sha256(self.state['v'] + plaintext[4:36]).digest() self.state['initpubR'][int(plaintext[1:4])] = plaintext[36:68] self.ratchetKey = deepcopy(self.state['initr']) self.state['R'] = deepcopy(self.state['initpubR']) DHR = '' for i in range(len(self.state['R'])): DHR = DHR + self.state['R'][i] DHR = hashlib.sha256(DHR).digest() self.state['RK'] = hashlib.sha256(self.state['v'] + self.genDH(self.state['v'], DHR)).digest() self.state['MK'] = pbkdf2(self.state['RK'], b'\x01', 10, prf='hmac-sha256') self.state['digest'] = '\x00' * 32 return 'Ratchet resync message received - System resynced!\n'
def derive_key(xml, password): """ Derive the encryption key from the password with the parameters given in the XML soup. :param xml: The XML :param password: the password :return: The derived key, hexlified """ if not password: raise ImportException("The XML KeyContainer specifies a derived " "encryption key, but no password given!") keymeth = xml.keycontainer.encryptionkey.derivedkey.keyderivationmethod derivation_algo = keymeth["algorithm"].split("#")[-1] if derivation_algo.lower() != "pbkdf2": raise ImportException("We only support PBKDF2 as Key derivation " "function!") salt = keymeth.find("salt").text.strip() keylength = keymeth.find("keylength").text.strip() rounds = keymeth.find("iterationcount").text.strip() r = pbkdf2(to_utf8(password), base64.b64decode(salt), int(rounds), int(keylength)) return binascii.hexlify(r)
def helper(secret=b("password"), salt=b("salt"), rounds=1, keylen=None, prf="hmac-sha1"): return pbkdf2(secret, salt, rounds, keylen, prf)
def test_05_init_totp_token(self): set_policy( name="allow_2step", action=["totp_2step=allow", "enrollTOTP=1", "delete"], scope=SCOPE.ADMIN, ) with self.app.test_request_context('/token/init', method='POST', data={"type": "totp", "genkey": "1", "2stepinit": "1"}, headers={'Authorization': self.at}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) result = json.loads(res.data.decode('utf8')).get("result") self.assertTrue(result.get("status") is True, result) self.assertTrue(result.get("value") is True, result) detail = json.loads(res.data.decode('utf8')).get("detail") serial = detail.get("serial") otpkey_url = detail.get("otpkey", {}).get("value") server_component = binascii.unhexlify(otpkey_url.split("/")[2]) google_url = detail["googleurl"]["value"] self.assertIn('2step_difficulty=10000', google_url) self.assertIn('2step_salt=8', google_url) self.assertIn('2step_output=20', google_url) self.assertEqual(detail['2step_difficulty'], 10000) self.assertEqual(detail['2step_salt'], 8) self.assertEqual(detail['2step_output'], 20) client_component = b"VRYSECRT" checksum = hashlib.sha1(client_component).digest()[:4] base32check_client_component = base64.b32encode(checksum + client_component).strip(b"=") # Try to do a 2stepinit on a second step will raise an error with self.app.test_request_context('/token/init', method='POST', data={"type": "totp", "2stepinit": "1", "serial": serial, "otpkey": base32check_client_component, "otpkeyformat": "base32check"}, headers={'Authorization': self.at}): res = self.app.full_dispatch_request() self.assertEqual(res.status_code, 400) result = json.loads(res.data.decode('utf8')).get("result") self.assertIn('2stepinit is only to be used in the first initialization step', result.get("error").get("message")) # Invalid base32check will raise an error with self.app.test_request_context('/token/init', method='POST', data={"type": "totp", "2stepinit": "1", "serial": serial, "otpkey": b"A" + base32check_client_component[1:], "otpkeyformat": "base32check"}, headers={'Authorization': self.at}): res = self.app.full_dispatch_request() self.assertEqual(res.status_code, 400) result = json.loads(res.data.decode('utf8')).get("result") self.assertIn('Malformed base32check data: Incorrect checksum', result.get("error").get("message")) # Authentication does not work yet! wrong_otp_value = HmacOtp().generate(key=server_component, counter=int(time.time() // 30)) with self.app.test_request_context('/validate/check', method='POST', data={"serial": serial, "pass": wrong_otp_value}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) result = json.loads(res.data.decode('utf8')) self.assertTrue(result.get("result").get("status")) self.assertFalse(result.get("result").get("value")) self.assertEqual(result.get("detail").get("message"), u'matching 1 tokens, Token is disabled') # Now doing the correct 2nd step with self.app.test_request_context('/token/init', method='POST', data={"type": "totp", "serial": serial, "otpkey": base32check_client_component, "otpkeyformat": "base32check"}, headers={'Authorization': self.at}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) result = json.loads(res.data.decode('utf8')).get("result") self.assertTrue(result.get("status") is True, result) self.assertTrue(result.get("value") is True, result) detail = json.loads(res.data.decode('utf8')).get("detail") otpkey_url = detail.get("otpkey", {}).get("value") otpkey = otpkey_url.split("/")[2] self.assertNotIn('2step', detail) # Now try to authenticate otpkey_bin = binascii.unhexlify(otpkey) otp_value = HmacOtp().generate(key=otpkey_bin, counter=int(time.time() // 30)) with self.app.test_request_context('/validate/check', method='POST', data={"serial": serial, "pass": otp_value}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) result = json.loads(res.data.decode('utf8')).get("result") self.assertEqual(result.get("status"), True) self.assertEqual(result.get("value"), True) # Check that the OTP key is what we expected it to be expected_secret = pbkdf2(binascii.hexlify(server_component), client_component, 10000, 20) self.assertEqual(otpkey_bin, expected_secret) with self.app.test_request_context('/token/'+ serial, method='DELETE', headers={'Authorization': self.at}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) delete_policy("allow_2step")
def test_06_force_totp_parameters(self): set_policy( name="force_2step", action=["totp_2step=force", "enrollTOTP=1", "delete"], scope=SCOPE.ADMIN, ) set_policy( name="2step_params", action=["totp_2step_difficulty=12345", "totp_2step_serversize=33", "totp_2step_clientsize=11"], scope=SCOPE.ENROLL, ) with self.app.test_request_context('/token/init', method='POST', data={"type": "totp", "genkey": "1", "2stepinit": "0", # will be forced nevertheless "2step_serversize": "3", "2step_clientsize": "4", "2step_difficulty": "33333", "timeStep": "60", "hashlib": "sha512", "otplen": "8", }, headers={'Authorization': self.at}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) result = json.loads(res.data.decode('utf8')).get("result") self.assertTrue(result.get("status") is True, result) self.assertTrue(result.get("value") is True, result) detail = json.loads(res.data.decode('utf8')).get("detail") serial = detail.get("serial") otpkey_url = detail.get("otpkey", {}).get("value") server_component = binascii.unhexlify(otpkey_url.split("/")[2]) google_url = detail["googleurl"]["value"] self.assertIn('2step_difficulty=12345', google_url) self.assertIn('2step_salt=11', google_url) self.assertIn('2step_output=64', google_url) # Authentication does not work yet! wrong_otp_value = HmacOtp(digits=8, hashfunc=hashlib.sha512).generate(key=server_component, counter=int(time.time() // 60)) with self.app.test_request_context('/validate/check', method='POST', data={"serial": serial, "pass": wrong_otp_value}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) result = json.loads(res.data.decode('utf8')) self.assertTrue(result.get("result").get("status")) self.assertFalse(result.get("result").get("value")) self.assertEqual(result.get("detail").get("message"), u'matching 1 tokens, Token is disabled') client_component = b"wrongsize" # 9 bytes hex_client_component = binascii.hexlify(client_component) # Supply a client secret of incorrect size with self.app.test_request_context('/token/init', method='POST', data={"type": "totp", "serial": serial, "otpkey": hex_client_component, }, headers={'Authorization': self.at}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 400, res) result = json.loads(res.data.decode('utf8')).get("result") self.assertFalse(result.get("status")) client_component = b"correctsize" # 11 bytes hex_client_component = binascii.hexlify(client_component) # Now doing the correct 2nd step with self.app.test_request_context('/token/init', method='POST', data={"type": "totp", "serial": serial, "otpkey": hex_client_component, "2step_serversize": "3", # will have no effect "2step_clientsize": "4", "2step_difficulty": "33333" }, headers={'Authorization': self.at}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) result = json.loads(res.data.decode('utf8')).get("result") self.assertTrue(result.get("status") is True, result) self.assertTrue(result.get("value") is True, result) detail = json.loads(res.data.decode('utf8')).get("detail") otpkey_url = detail.get("otpkey", {}).get("value") otpkey = otpkey_url.split("/")[2] # Now try to authenticate otpkey_bin = binascii.unhexlify(otpkey) otp_value = HmacOtp(digits=8, hashfunc=hashlib.sha512).generate(key=otpkey_bin, counter=int(time.time() // 60)) with self.app.test_request_context('/validate/check', method='POST', data={"serial": serial, "pass": otp_value}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) result = json.loads(res.data.decode('utf8')).get("result") self.assertEqual(result.get("status"), True) self.assertEqual(result.get("value"), True) # Check serversize self.assertEqual(len(server_component), 33) # Check that the OTP key is what we expected it to be expected_secret = pbkdf2(binascii.hexlify(server_component), client_component, 12345, 64) self.assertEqual(otpkey_bin, expected_secret) with self.app.test_request_context('/token/'+ serial, method='DELETE', headers={'Authorization': self.at}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) delete_policy("force_2step") delete_policy("2step_params")
def _pbkdf2(text): return pbkdf2(text, 'noggnogg', 1337).encode('hex').lower()
def createState(self, other_name, mkey, mode=None, other_identityKey=None, other_ratchetKey=None): self.mode = mode if self.mode is None: # mode not selected raise (Axolotl_exception('Mode must be set')) if self.mode: # alice mode RK = pbkdf2(mkey, b'\x00', 10, prf='hmac-sha256') HKs = None HKr = pbkdf2(mkey, b'\x02', 10, prf='hmac-sha256') NHKs = pbkdf2(mkey, b'\x03', 10, prf='hmac-sha256') NHKr = pbkdf2(mkey, b'\x04', 10, prf='hmac-sha256') CKs = None CKr = pbkdf2(mkey, b'\x06', 10, prf='hmac-sha256') DHRs_priv = None DHRs = None DHRr = other_ratchetKey CONVid = pbkdf2(mkey, b'\x07', 10, prf='hmac-sha256') Ns = 0 Nr = 0 PNs = 0 ratchet_flag = True else: # bob mode RK = pbkdf2(mkey, b'\x00', 10, prf='hmac-sha256') HKs = pbkdf2(mkey, b'\x02', 10, prf='hmac-sha256') HKr = None NHKs = pbkdf2(mkey, b'\x04', 10, prf='hmac-sha256') NHKr = pbkdf2(mkey, b'\x03', 10, prf='hmac-sha256') CKs = pbkdf2(mkey, b'\x06', 10, prf='hmac-sha256') CKr = None DHRs_priv = self.state['DHRs_priv'] DHRs = self.state['DHRs'] DHRr = None CONVid = pbkdf2(mkey, b'\x07', 10, prf='hmac-sha256') Ns = 0 Nr = 0 PNs = 0 ratchet_flag = False DHIr = other_identityKey self.state = \ {'name': self.name, 'other_name': other_name, 'RK': RK, 'HKs': HKs, 'HKr': HKr, 'NHKs': NHKs, 'NHKr': NHKr, 'CKs': CKs, 'CKr': CKr, 'DHIs_priv': self.state['DHIs_priv'], 'DHIs': self.state['DHIs'], 'DHIr': DHIr, 'DHRs_priv': DHRs_priv, 'DHRs': DHRs, 'DHRr': DHRr, 'CONVid': CONVid, 'Ns': Ns, 'Nr': Nr, 'PNs': PNs, 'ratchet_flag': ratchet_flag, } self.ratchetKey = False self.ratchetPKey = False
def hash(password, salt): return pbkdf2(to_bytes(password), to_bytes(salt), 10000).encode('hex')
def _calc_checksum(self, secret): if isinstance(secret, unicode): secret = secret.encode("utf-8") hash = pbkdf2(secret, self.salt.encode("ascii"), self.rounds, keylen=None, prf=self._prf) return b64encode(hash).rstrip().decode("ascii")