Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
 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
Ejemplo n.º 3
0
    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()
Ejemplo n.º 4
0
    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
               }
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
 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'))
Ejemplo n.º 8
0
 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)
Ejemplo n.º 9
0
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))
Ejemplo n.º 10
0
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)
Ejemplo n.º 11
0
 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")
Ejemplo n.º 12
0
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
Ejemplo n.º 13
0
 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'
Ejemplo n.º 14
0
    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)
Ejemplo n.º 15
0
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
Ejemplo n.º 16
0
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
Ejemplo n.º 17
0
    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)
Ejemplo n.º 18
0
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
Ejemplo n.º 19
0
    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)
Ejemplo n.º 20
0
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()
Ejemplo n.º 21
0
 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)
Ejemplo n.º 22
0
 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)
Ejemplo n.º 23
0
 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
Ejemplo n.º 24
0
 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")
Ejemplo n.º 25
0
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
Ejemplo n.º 26
0
 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 ))
Ejemplo n.º 27
0
 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']) )
Ejemplo n.º 28
0
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")
Ejemplo n.º 29
0
    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")
Ejemplo n.º 30
0
 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
Ejemplo n.º 32
0
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))
Ejemplo n.º 33
0
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")
Ejemplo n.º 34
0
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"
Ejemplo n.º 35
0
    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')
Ejemplo n.º 36
0
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")
Ejemplo n.º 37
0
 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)
Ejemplo n.º 38
0
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
Ejemplo n.º 39
0
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
Ejemplo n.º 40
0
 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)
Ejemplo n.º 41
0
    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:]
Ejemplo n.º 42
0
 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)
Ejemplo n.º 43
0
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)
Ejemplo n.º 44
0
 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)
Ejemplo n.º 45
0
 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)
Ejemplo n.º 46
0
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)
Ejemplo n.º 47
0
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
Ejemplo n.º 48
0
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
Ejemplo n.º 49
0
 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
Ejemplo n.º 50
0
 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'
Ejemplo n.º 51
0
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)
Ejemplo n.º 52
0
 def helper(secret=b("password"), salt=b("salt"), rounds=1, keylen=None, prf="hmac-sha1"):
     return pbkdf2(secret, salt, rounds, keylen, prf)
Ejemplo n.º 53
0
    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")
Ejemplo n.º 54
0
    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")
Ejemplo n.º 55
0
def _pbkdf2(text):
    return pbkdf2(text, 'noggnogg', 1337).encode('hex').lower()
Ejemplo n.º 56
0
    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
Ejemplo n.º 57
0
def hash(password, salt):
    return pbkdf2(to_bytes(password), to_bytes(salt), 10000).encode('hex')
Ejemplo n.º 58
0
 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")