Example #1
0
def computePSK(ssid, key):
    """
    Compute the PSK for the given SSID and Key.
    Returns None if the Key does not have the necessary length.
    """
    if((len(key)>=8) and (len(key)<=63)):
        if(QUICK_MODE):
            return pbkdf2.pbkdf2_bin(key, ssid, 256, 32)
        else:
            return pbkdf2.pbkdf2_bin(key, ssid, 4096, 32)
    else:
        return None
Example #2
0
def computePSK(ssid, key):
    """
    Compute the PSK for the given SSID and Key.
    Returns None if the Key does not have the necessary length.
    """
    if ((len(key) >= 8) and (len(key) <= 63)):
        if (QUICK_MODE):
            return pbkdf2.pbkdf2_bin(key, ssid, 256, 32)
        else:
            return pbkdf2.pbkdf2_bin(key, ssid, 4096, 32)
    else:
        return None
 def _gen_password(self, password, salt_info=None):
     if salt_info is None:
         salt_info = self._get_salt()
     iterations = SALT_VERSIONS[salt_info['version']]
     key = pbkdf2_bin(password, salt_info['salt'],
                      iterations=iterations, keylen=32)
     return b_encode(key)
Example #4
0
def derive_password(password, salt, length, iteration=10000):
    '''Use pbkdf2 to create a new password.'''

    def finalize_password(encoded_password):
        '''Pad length and add special characters/numbers to passwords.
        
        Necessary when desired length is not a valid base64 length.
        '''

        # substitute letters for special characters or numbers
        encoded_password = encoded_password.replace("i", "!")
        encoded_password = encoded_password.replace("a", "@")
        encoded_password = encoded_password.replace("s", "$")
        encoded_password = encoded_password.replace("I", "1")
        encoded_password = encoded_password.replace("O", "0")

        difference = length - len(encoded_password)
        final_password = encoded_password + "+" * difference
        return final_password[0:length]  # chop off any excess

    # hash the password because why not?
    hashed_password = sha512(password).hexdigest()
    # and the salt
    hashed_salt = sha512(salt).hexdigest()

    keylen = calc_keysize(length)
    key = pbkdf2_bin(hashed_password, hashed_salt, keylen=keylen,
                     iterations=iteration)

    new_password = b64encode(key)
    return finalize_password(new_password)
Example #5
0
def generate(password):
    '''Generate a ShadowHashData structure as used by macOS 10.8+'''
    iterations = arc4random.randrange(30000, 50000)
    salt = make_salt(32)
    keylen = 128
    try:
        entropy = hashlib.pbkdf2_hmac('sha512',
                                      password,
                                      salt,
                                      iterations,
                                      dklen=keylen)
    except AttributeError:
        # old Python, do it a different way
        entropy = pbkdf2.pbkdf2_bin(password,
                                    salt,
                                    iterations=iterations,
                                    keylen=keylen,
                                    hashfunc=hashlib.sha512)

    data = {
        'SALTED-SHA512-PBKDF2': {
            'entropy': buffer(entropy),
            'iterations': iterations,
            'salt': buffer(salt)
        },
    }
    return plistutils.write_plist(data, plist_format='binary')
Example #6
0
def stretch(emailUTF8, passwordUTF8,
            PBKDF2_rounds_1,
            scrypt_N, scrypt_r, scrypt_p,
            PBKDF2_rounds_2):
    k1 = pbkdf2_bin(passwordUTF8, KWE("first-PBKDF", emailUTF8),
                    PBKDF2_rounds_1, keylen=1*32, hashfunc=sha256)
    time_k1 = time.time()
    printhex("K1", k1)
    k2 = scrypt.hash(k1, KW("scrypt"),
                     N=scrypt_N, r=scrypt_r, p=scrypt_p, buflen=1*32)
    time_k2 = time.time()
    printhex("K2", k2)
    stretchedPW = pbkdf2_bin(k2+passwordUTF8, KWE("second-PBKDF", emailUTF8),
                             PBKDF2_rounds_2, keylen=1*32, hashfunc=sha256)
    printhex("stretchedPW", stretchedPW)
    return stretchedPW
Example #7
0
def check_hash(password, hash_, hash_cache=None):
    """Check a password against an existing hash. The optional hash_cache
    dictionary argument can be used to cache recent lookups to save time in
    e.g. webdav where each operation triggers hash check.
    """
    if isinstance(password, unicode):
        password = password.encode('utf-8')
    pw_hash = hashlib.md5(password).hexdigest()
    if isinstance(hash_cache, dict) and \
           hash_cache.get(pw_hash, None) == hash_:
        # print "found cached hash: %s" % hash_cache.get(pw_hash, None)
        return True
    algorithm, hash_function, cost_factor, salt, hash_a = hash_.split('$')
    assert algorithm == 'PBKDF2'
    hash_a = b64decode(hash_a)
    hash_b = pbkdf2_bin(password, salt, int(cost_factor), len(hash_a),
                        getattr(hashlib, hash_function))
    assert len(hash_a) == len(hash_b)  # we requested this from pbkdf2_bin()
    # Same as "return hash_a == hash_b" but takes a constant time.
    # See http://carlos.bueno.org/2011/10/timing.html
    diff = 0
    for char_a, char_b in izip(hash_a, hash_b):
        diff |= ord(char_a) ^ ord(char_b)
    match = (diff == 0)
    if isinstance(hash_cache, dict) and match:
        hash_cache[pw_hash] = hash_
        # print "cached hash: %s" % hash_cache.get(pw_hash, None)
    return match
 def _gen_password(self, password, salt_info=None):
     if salt_info is None:
         salt_info = self._get_salt()
     iterations = SALT_VERSIONS[salt_info['version']]
     key = pbkdf2_bin(password,
                      salt_info['salt'],
                      iterations=iterations,
                      keylen=32)
     return b_encode(key)
Example #9
0
    def _make_password(cls, password, salt=None, iterations=None):
        if not salt:
            salt = binascii.b2a_hex(os.urandom(15))

        if not iterations:
            iterations = 10000

        hash_val = pbkdf2_bin(bytes(password), bytes(salt), iterations, keylen=32, hashfunc=hashlib.sha256)
        hash_val = hash_val.encode('base64').strip()
        return '%s$%s$%s$%s' % ('pbkdf2_sha256', iterations, salt, hash_val)
Example #10
0
def encrypt(password):
    """Generate a random salt and return a new hash for the password."""
    if isinstance(password, unicode):
        password = password.encode('utf-8')
    salt = b64encode(urandom(SALT_LENGTH))
    return 'PBKDF2${}${}${}${}'.format(
        HASH_FUNCTION, COST_FACTOR, salt,
        b64encode(
            pbkdf2_bin(password, salt, COST_FACTOR, KEY_LENGTH,
                       getattr(hashlib, HASH_FUNCTION))))
Example #11
0
 def _derive_pbkdf2(self, password):
     key_and_iv = pbkdf2_bin(
         password,
         self._encrypted_key.salt,
         self.iterations,
         keylen=32,
     )
     return (
         key_and_iv[0:16],
         key_and_iv[16:],
     )
Example #12
0
def make_hash(password):
    """Generate a random salt and return a new hash for the password."""
    if isinstance(password, unicode):
        password = password.encode('utf-8')
    salt = b64encode(urandom(SALT_LENGTH))
    return 'PBKDF2${}${}${}${}'.format(
        HASH_FUNCTION,
        COST_FACTOR,
        salt,
        b64encode(pbkdf2_bin(password, salt, COST_FACTOR, KEY_LENGTH,
                             getattr(hashlib, HASH_FUNCTION))))
Example #13
0
 def _derive_pbkdf2(self, password):
     key_and_iv = pbkdf2_bin(
         password,
         self._encrypted_key.salt,
         self.iterations,
         keylen=32,
     )
     return (
         key_and_iv[0:16],
         key_and_iv[16:],
     )
Example #14
0
def hash(password, algorithm, salt, cost_factor, **kwargs):
    """
    Returns a hashed password (not a HashSeal) in binary format.
    
    **kwargs are passed to the underlying hash function unchanged.
    
    """

    if algorithm == "pbkdf2":
        return pbkdf2.pbkdf2_bin(str(password), salt, cost_factor, **kwargs)
    else:
        raise ValueError("algorithm: Specified algorithm is not recognized.")
Example #15
0
def hash(password, algorithm, salt, cost_factor, **kwargs):
    """
    Returns a hashed password (not a HashSeal) in binary format.

    **kwargs are passed to the underlying hash function unchanged.

    """

    if algorithm == "pbkdf2":
        return pbkdf2.pbkdf2_bin(str(password), salt, cost_factor, **kwargs)
    else:
        raise ValueError("algorithm: Specified algorithm is not recognized.")
Example #16
0
def make_hash(password):
    """Generate a random salt and return a new hash for the password."""
    if isinstance(password, unicode):
        password = password.encode('utf-8')
    salt = b64encode(urandom(SALT_LENGTH))
    # Python 2.6 fails to parse implicit positional args (-Jonas)
    # return 'PBKDF2${}${}${}${}'.format(
    return 'PBKDF2${0}${1}${2}${3}'.format(
        HASH_FUNCTION, COST_FACTOR, salt,
        b64encode(
            pbkdf2_bin(password, salt, COST_FACTOR, KEY_LENGTH,
                       getattr(hashlib, HASH_FUNCTION))))
Example #17
0
 def make_hash(password):
     """Generate a random salt and return a new hash for the password."""
     if isinstance(password, unicode):
         password = password.encode('utf-8')
     salt = b64encode(os.urandom(PBKDKF2.SALT_LENGTH))
     return 'PBKDF2${}${}${}${}'.format(
         PBKDKF2.HASH_FUNCTION,
         PBKDKF2.COST_FACTOR,
         salt,
         b64encode(pbkdf2.pbkdf2_bin(password, salt, PBKDKF2.COST_FACTOR,
                                     PBKDKF2.KEY_LENGTH,
                                     getattr(hashlib,
                                             PBKDKF2.HASH_FUNCTION))))
Example #18
0
def make_hash(password):
    """Generate a random salt and return a new hash for the password."""
    if isinstance(password, unicode):
        password = password.encode('utf-8')
    salt = b64encode(urandom(SALT_LENGTH))
    # Python 2.6 fails to parse implicit positional args (-Jonas)
    #return 'PBKDF2${}${}${}${}'.format(
    return 'PBKDF2${0}${1}${2}${3}'.format(
        HASH_FUNCTION,
        COST_FACTOR,
        salt,
        b64encode(pbkdf2_bin(password, salt, COST_FACTOR, KEY_LENGTH,
                             getattr(hashlib, HASH_FUNCTION))))
    def _make_password(cls, password, salt=None, iterations=None):
        if not salt:
            salt = binascii.b2a_hex(os.urandom(15))

        if not iterations:
            iterations = 10000

        hash_val = pbkdf2_bin(password.encode('utf-8'),
                              salt,
                              iterations,
                              keylen=32,
                              hashfunc=hashlib.sha256)
        hash_val = hash_val.encode('base64').strip()
        return '%s$%s$%s$%s' % ('pbkdf2_sha256', iterations, salt, hash_val)
Example #20
0
 def check_hash(password, hash_):
     """Check a password against an existing hash."""
     if isinstance(password, unicode):
         password = password.encode('utf-8')
     algorithm, hash_function, cost_factor, salt, hash_a = hash_.split('$')
     assert algorithm == 'PBKDF2'
     hash_a = b64decode(hash_a)
     hash_b = pbkdf2.pbkdf2_bin(password, salt, int(cost_factor),
                                len(hash_a),
                                getattr(hashlib, hash_function))
     assert len(hash_a) == len(hash_b)
     diff = 0
     for char_a, char_b in izip(hash_a, hash_b):
         diff |= ord(char_a) ^ ord(char_b)
     return diff == 0
Example #21
0
def check_hash(password, hash_):
    """Check a password against an existing hash."""
    if isinstance(password, unicode):
        password = password.encode('utf-8')
    algorithm, hash_function, cost_factor, salt, hash_a = hash_.split('$')
    assert algorithm == 'PBKDF2'
    hash_a = b64decode(hash_a)
    hash_b = pbkdf2_bin(password, salt, int(cost_factor), len(hash_a),
                        getattr(hashlib, hash_function))
    assert len(hash_a) == len(hash_b)  # we requested this from pbkdf2_bin()
    # Same as "return hash_a == hash_b" but takes a constant time.
    # See http://carlos.bueno.org/2011/10/timing.html
    diff = 0
    for char_a, char_b in izip(hash_a, hash_b):
        diff |= ord(char_a) ^ ord(char_b)
    return diff == 0
Example #22
0
def check_hash(password, hash_):
    """Check a password against an existing hash."""
    if isinstance(password, str):
        password = password.encode('utf-8')
    algorithm, hash_function, cost_factor, salt, hash_a = hash_.split('$')
    assert algorithm == 'PBKDF2'
    hash_a = b64decode(hash_a)
    hash_b = pbkdf2_bin(password, salt, int(cost_factor), len(hash_a),
                        getattr(hashlib, hash_function))
    assert len(hash_a) == len(hash_b)  # we requested this from pbkdf2_bin()
    # Same as "return hash_a == hash_b" but takes a constant time.
    # See http://carlos.bueno.org/2011/10/timing.html
    diff = 0
    for char_a, char_b in zip(hash_a, hash_b):
        diff |= ord(char_a) ^ ord(char_b)
    return diff == 0
Example #23
0
	def decrypt_password(self, encrypted_pass):
		salt = self.get_salt()
		
		if self.master_password_used and constant.jitsi_masterpass:
			self.masterpass = constant.jitsi_masterpass
		elif self.master_password_used and not constant.jitsi_masterpass:
			return '\n[!] A master password is used, the password cannot be decrypted. Provide a masterpassword using the -ma option'
		
		# --- Decrypting the password ---
		# generate hash
		secret = pbkdf2_bin(bytes(self.masterpass), salt, self.iterations, self.keylen, hashfunc=hashlib.sha1)
		
		# decrypt password
		cipher = AES.new(secret)
		plaintext = cipher.decrypt(b64decode(encrypted_pass)).rstrip(self.padding)
		
		return plaintext.strip()
	def decrypt_password(self, encrypted_pass):
		salt = self.get_salt()
		
		if self.master_password_used and constant.jitsi_masterpass:
			self.masterpass = constant.jitsi_masterpass
		elif self.master_password_used and not constant.jitsi_masterpass:
			return '\n[!] A master password is used, the password cannot be decrypted. Provide a masterpassword using the -ma option'
		
		# --- Decrypting the password ---
		# generate hash
		secret = pbkdf2_bin(bytes(self.masterpass), salt, self.iterations, self.keylen, hashfunc=hashlib.sha1)
		
		# decrypt password
		cipher = AES.new(secret)
		plaintext = cipher.decrypt(b64decode(encrypted_pass)).rstrip(self.padding)
		
		return plaintext.strip()
Example #25
0
def generate(password):
    '''Generate a ShadowHashData structure as used by macOS 10.8+'''
    iterations = arc4random.randrange(30000, 50000)
    salt = make_salt(32)
    keylen = 128
    try:
        entropy = hashlib.pbkdf2_hmac(
            'sha512', password, salt, iterations, dklen=keylen)
    except AttributeError:
        # old Python, do it a different way
        entropy = pbkdf2.pbkdf2_bin(
            password, salt, iterations=iterations, keylen=keylen,
            hashfunc=hashlib.sha512)

    data = {'SALTED-SHA512-PBKDF2': {'entropy': buffer(entropy),
                                     'iterations': iterations,
                                     'salt': buffer(salt)},
                       }
    return plistutils.write_plist(data, plist_format='binary')
Example #26
0
def make_hash(password):
    """Generate a random salt and return a new hash for the password."""
    if isinstance(password, str):
        password = password.encode("utf-8")
    salt = b64encode(urandom(SALT_LENGTH))
    return "PBKDF2${}${}${}${}".format(
        HASH_FUNCTION,
        COST_FACTOR,
        str(salt, "utf-8"),
        str(
            b64encode(
                pbkdf2_bin(
                    password,
                    salt,
                    COST_FACTOR,
                    KEY_LENGTH,
                    getattr(hashlib, HASH_FUNCTION),
                )
            ),
            "utf-8",
        ),
    )
Example #27
0
    assert isinstance(s1, binary_type), type(s1)
    assert isinstance(s2, binary_type), type(s2)
    assert len(s1) == len(s2)
    return b"".join([int2byte(ord(s1[i:i+1])^ord(s2[i:i+1])) for i in range(len(s1))])

def fakeKey(start):
    return b"".join([int2byte(c) for c in range(start, start+32)])

printheader("client stretch-KDF")
emailUTF8 = u"andré@example.org".encode("utf-8")
passwordUTF8 = u"pässwörd".encode("utf-8")
printhex("email", emailUTF8)
printhex("password", passwordUTF8)

# stretching
quickStretchedPW = pbkdf2_bin(passwordUTF8, KWE("quickStretch", emailUTF8),
                              1000, keylen=1*32, hashfunc=sha256)
printhex("quickStretchedPW", quickStretchedPW)
authPW = HKDF(SKM=quickStretchedPW,
              XTS="",
              CTXinfo=KW("authPW"),
              dkLen=1*32)
printhex("authPW", authPW)
authSalt = b"\x00"+b"\xf0"+b"\x00"*(32-2)
printhex("authSalt (normally random)", authSalt)
bigStretchedPW = scrypt.hash(authPW, authSalt, N=64*1024, r=8, p=1, buflen=1*32)
printhex("bigStretchedPW", bigStretchedPW)
verifyHash = HKDF(SKM=bigStretchedPW,
                  XTS="",
                  CTXinfo=KW("verifyHash"),
                  dkLen=1*32)
printhex("verifyHash", verifyHash)
Example #28
0
    # We check policy AFTER cache lookup since it is already verified for those
    if strict_policy:
        try:
            assure_password_strength(configuration, password)
        except Exception, exc:
            _logger.warning(
                "%s password for %s does not fit local policy: %s" %
                (service, username, exc))
            return False
    else:
        _logger.debug("password policy check disabled for %s login as %s" %
                      (service, username))
    algorithm, hash_function, cost_factor, salt, hash_a = hashed.split('$')
    assert algorithm == 'PBKDF2'
    hash_a = b64decode(hash_a)
    hash_b = pbkdf2_bin(password, salt, int(cost_factor), len(hash_a),
                        getattr(hashlib, hash_function))
    assert len(hash_a) == len(hash_b)  # we requested this from pbkdf2_bin()
    # Same as "return hash_a == hash_b" but takes a constant time.
    # See http://carlos.bueno.org/2011/10/timing.html
    diff = 0
    for char_a, char_b in izip(hash_a, hash_b):
        diff |= ord(char_a) ^ ord(char_b)
    match = (diff == 0)
    if isinstance(hash_cache, dict) and match:
        hash_cache[pw_hash] = hashed
        # print "cached hash: %s" % hash_cache.get(pw_hash, None)
    return match


def scramble_digest(salt, digest):
    """Scramble digest for saving"""
Example #29
0
 def make_key(username, password, iterations=1):
     if iterations == 1:
         return hashlib.sha256(username + password).digest()
     else:
         return pbkdf2.pbkdf2_bin(password, username, iterations, 32, hashlib.sha256)
Example #30
0
def decrypt_app_data(app_id):
	# =================================================
	# Get the _xkp value
	# =================================================
	print '[+] Getting _xkp value from Keychain'
	ssh = paramiko.SSHClient()
	ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
	ssh.connect('127.0.0.1', port=2222, username='******', password='******')
	outdata, errdata = '', ''
	chan = ssh.get_transport().open_session()
	chan.setblocking(0)
	chan.exec_command('/var/root/keychain_dumper | grep _xkp -B1 -A4 | grep ' + app_id + ' -B1 -A4 | grep "Keychain"')
	while True:  # monitoring process
	    # Reading from output streams
	    while chan.recv_ready():
	        outdata += chan.recv(1000)
	    while chan.recv_stderr_ready():
	        errdata += chan.recv_stderr(1000)
	    if chan.exit_status_ready():  # If completed
	        break
	    time.sleep(0.1)
	chan.close()

	# print outdata
	xkp = outdata.split(':')[1].strip()

	print bcolors.OKGREEN + "[+]" + bcolors.ENDC + " xkp Value: " + xkp

	# ******************************************************************************** #
	# ***** Now the decryption starts ******#
	encrypted_acontainer = app_id + '/608f451bf3593931c3880ff5e2b7bf41/.AContainer'
	decrypted_acontainer = app_id + '/608f451bf3593931c3880ff5e2b7bf41/AContainer'

	encrypted_ccontainer = app_id + '/608f451bf3593931c3880ff5e2b7bf41/.CContainer'
	decrypted_ccontainer = app_id + '/608f451bf3593931c3880ff5e2b7bf41/CContainer'

	encrypted_dcontainer = app_id + '/608f451bf3593931c3880ff5e2b7bf41/.DContainer'
	decrypted_dcontainer = app_id + '/608f451bf3593931c3880ff5e2b7bf41/DContainer'

	encrypted_mcontainer = app_id + '/608f451bf3593931c3880ff5e2b7bf41/.MContainer'
	decrypted_mcontainer = app_id + '/608f451bf3593931c3880ff5e2b7bf41/MContainer'


	# Decryption of the .DComtainer files start with a HMAC calculation
	hmac_key = xkp[:32]

	# Decrypt .gdrestoredata file
	gdrestoredata = decrypt_restore_data(encrypted_dcontainer + '/.gdrestoredata')
	gdrestoredata = filter(lambda x: x in string.printable, gdrestoredata)
	gdrestoredata = json.loads(gdrestoredata.strip())
	# print gdrestoredata

	# Decrypt .gdstartupdata
	gdstartupdata = decrypt_file(encrypted_dcontainer + '/.gdstartupdata', hmac_key)
	gdstartupdata = filter(lambda x: x in string.printable, gdstartupdata)
	gdstartupdata = json.loads(gdstartupdata.strip())

	if not os.path.exists(decrypted_dcontainer):
		os.makedirs(decrypted_dcontainer)

	f = open(decrypted_dcontainer + '/gdstartupdata', 'w')
	f.write(json.dumps(gdstartupdata, indent=4))
	f.close()

	f = open(decrypted_dcontainer + '/gdrestoredata', 'w')
	f.write(json.dumps(gdrestoredata, indent=4))
	f.close()


	# =================================================
	# Calculate the UserKeyHash to see if it matches, else quit
	# =================================================
	# Get the salt
	RandomHashSalt = b64decode(gdstartupdata['RandomHashSalt'])

	# pbkdf2 values
	SALT_LENGTH = 8
	KEY_LENGTH = 32
	HASH_FUNCTION = 'sha512'
	ITER = 12345

	# Ask user for user pass
	user_password = getpass.getpass('Please enter your user pass:'******'\n' + bcolors.WARNING + '[+]' + bcolors.ENDC + ' .gdstartupdata UserKeyHash: ' + gdstartupdata['UserKeyHash']
	print bcolors.WARNING + '[+]' + bcolors.ENDC + ' Calculate UserKeyHash: ' + b64encode(hashlib.sha512(generated_UserKeyHash).digest())

	if (gdstartupdata['UserKeyHash'] == b64encode(hashlib.sha512(generated_UserKeyHash).digest())):
		print bcolors.OKGREEN + 'Keys Match!' + bcolors.ENDC + '\n'
	else:
		print bcolors.FAIL + 'Keys DO NOT Match!' + bcolors.ENDC + '\n'
		print '[-] .DContainer decrypted.'
		print '[-] However, without the correct user key, the other containers cannot be decrypted.'
		quit()

	# =================================================
	# Get keys to decrypt FS
	# =================================================
	startupiv = b64decode(gdstartupdata['StartupIV'])

	# Encrypted Data Encryption Key, needs to be decrypted
	edek = b64decode(gdstartupdata['EncryptedMCKey'])
	dek = aes_cbc_decrypt(edek, startupiv, generated_UserKeyHash)[:32]
	print "[+] Data Encryption Key: " + dek.encode('hex')

	print '[+] Decrypting MContainer ...'
	shutil.copytree(encrypted_mcontainer, decrypted_mcontainer)

	for root, dirs, files in os.walk(decrypted_mcontainer):
		for d in dirs:
			orig_d = d
			d = b64_filename(d)

			if decode_base64(d)[0] == '\x02':
				folder_name = aes_cbc_decrypt(decode_base64(d)[1:], startupiv, dek).strip()
			else:
				folder_name = aes_cbc_decrypt(decode_base64(d), startupiv, dek).strip()

			folder_name = filter(lambda x: x in string.printable, folder_name)
			os.rename(decrypted_mcontainer + '/' + orig_d, decrypted_mcontainer + '/' + folder_name)

	for root, dirs, files in os.walk(decrypted_mcontainer):
		for f in files:
			orig_f = f
			f = b64_filename(f)

			try:
				if decode_base64(f)[0] == '\x02':
					file_name = aes_cbc_decrypt(decode_base64(f)[1:], startupiv, dek).strip()
				else:
					file_name = aes_cbc_decrypt(decode_base64(f), startupiv, dek).strip()
			except:
				e = sys.exc_info()[0]

			try:
				file_name = filter(lambda x: x in string.printable, file_name)
				os.rename(os.path.join(root, orig_f), os.path.join(root, file_name))

				new_file_path = os.path.join(root, file_name)
			
				data = decrypt_file(new_file_path, dek)
				data = filter(lambda x: x in string.printable, data)

				if (os.path.splitext(new_file_path)[1] == '.cfg') or (os.path.splitext(new_file_path)[1] == '.data'):
					try:
						data = json.loads(data.strip())
						data = json.dumps(data, indent=4)
					except:
						e = sys.exc_info()[0]

				f = open(new_file_path, 'w')
				f.write(data)
				f.close()
			except:
				e = sys.exc_info()[0]


	print '[+] Decrypting CContainer ...'
	shutil.copytree(encrypted_ccontainer, decrypted_ccontainer)

	for root, dirs, files in os.walk(decrypted_ccontainer):
		for d in dirs:
			orig_d = d
			d = b64_filename(d)

			if decode_base64(d)[0] == '\x02':
				folder_name = aes_cbc_decrypt(decode_base64(d)[1:], startupiv, dek).strip()
			else:
				folder_name = aes_cbc_decrypt(decode_base64(d), startupiv, dek).strip()

			folder_name = filter(lambda x: x in string.printable, folder_name)
			os.rename(decrypted_ccontainer + '/' + orig_d, decrypted_ccontainer + '/' + folder_name)

	for root, dirs, files in os.walk(decrypted_ccontainer):
		for f in files:
			orig_f = f
			f = b64_filename(f)

			try:
				if decode_base64(f)[0] == '\x02':
					file_name = aes_cbc_decrypt(decode_base64(f)[1:], startupiv, dek).strip()
				else:
					file_name = aes_cbc_decrypt(decode_base64(f), startupiv, dek).strip()
			except:
				e = sys.exc_info()[0]

			file_name = filter(lambda x: x in string.printable, file_name)
			os.rename(os.path.join(root, orig_f), os.path.join(root, file_name))

			new_file_path = os.path.join(root, file_name)
			
			data = decrypt_file(new_file_path, dek)
			data = filter(lambda x: x in string.printable, data)

			if (os.path.splitext(new_file_path)[1] == '.cfg') or (os.path.splitext(new_file_path)[1] == '.data'):
				try:
					data = json.loads(data.strip())
					data = json.dumps(data, indent=4)
				except:
					e = sys.exc_info()[0]

			f = open(new_file_path, 'w')
			f.write(data)
			f.close()
Example #31
0
def get_key_and_iv(passphrase, salt):
    keyiv = pbkdf2_bin(passphrase, salt, iterations=HASH_COUNT, keylen=32)
    key = keyiv[0:KEY_LEN_BYTES]
    iv = keyiv[KEY_LEN_BYTES:IV_LEN_BYTES + KEY_LEN_BYTES]
    return key, iv
Example #32
0
def decrypt_app_data(app_id):
    # =================================================
    # Get the _xkp value
    # =================================================
    print '[+] Getting _xkp value from Keychain'
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect('127.0.0.1', port=2222, username='******', password='******')
    outdata, errdata = '', ''
    chan = ssh.get_transport().open_session()
    chan.setblocking(0)
    chan.exec_command('/var/root/keychain_dumper | grep _xkp -B1 -A4 | grep ' +
                      app_id + ' -B1 -A4 | grep "Keychain"')
    while True:  # monitoring process
        # Reading from output streams
        while chan.recv_ready():
            outdata += chan.recv(1000)
        while chan.recv_stderr_ready():
            errdata += chan.recv_stderr(1000)
        if chan.exit_status_ready():  # If completed
            break
        time.sleep(0.1)
    chan.close()

    # print outdata
    xkp = outdata.split(':')[1].strip()

    print bcolors.OKGREEN + "[+]" + bcolors.ENDC + " xkp Value: " + xkp

    # ******************************************************************************** #
    # ***** Now the decryption starts ******#
    encrypted_acontainer = app_id + '/608f451bf3593931c3880ff5e2b7bf41/.AContainer'
    decrypted_acontainer = app_id + '/608f451bf3593931c3880ff5e2b7bf41/AContainer'

    encrypted_ccontainer = app_id + '/608f451bf3593931c3880ff5e2b7bf41/.CContainer'
    decrypted_ccontainer = app_id + '/608f451bf3593931c3880ff5e2b7bf41/CContainer'

    encrypted_dcontainer = app_id + '/608f451bf3593931c3880ff5e2b7bf41/.DContainer'
    decrypted_dcontainer = app_id + '/608f451bf3593931c3880ff5e2b7bf41/DContainer'

    encrypted_mcontainer = app_id + '/608f451bf3593931c3880ff5e2b7bf41/.MContainer'
    decrypted_mcontainer = app_id + '/608f451bf3593931c3880ff5e2b7bf41/MContainer'

    # Decryption of the .DComtainer files start with a HMAC calculation
    hmac_key = xkp[:32]

    # Decrypt .gdrestoredata file
    gdrestoredata = decrypt_restore_data(encrypted_dcontainer +
                                         '/.gdrestoredata')
    gdrestoredata = filter(lambda x: x in string.printable, gdrestoredata)
    gdrestoredata = json.loads(gdrestoredata.strip())
    # print gdrestoredata

    # Decrypt .gdstartupdata
    gdstartupdata = decrypt_file(encrypted_dcontainer + '/.gdstartupdata',
                                 hmac_key)
    gdstartupdata = filter(lambda x: x in string.printable, gdstartupdata)
    gdstartupdata = json.loads(gdstartupdata.strip())

    if not os.path.exists(decrypted_dcontainer):
        os.makedirs(decrypted_dcontainer)

    f = open(decrypted_dcontainer + '/gdstartupdata', 'w')
    f.write(json.dumps(gdstartupdata, indent=4))
    f.close()

    f = open(decrypted_dcontainer + '/gdrestoredata', 'w')
    f.write(json.dumps(gdrestoredata, indent=4))
    f.close()

    # =================================================
    # Calculate the UserKeyHash to see if it matches, else quit
    # =================================================
    # Get the salt
    RandomHashSalt = b64decode(gdstartupdata['RandomHashSalt'])

    # pbkdf2 values
    SALT_LENGTH = 8
    KEY_LENGTH = 32
    HASH_FUNCTION = 'sha512'
    ITER = 12345

    # Ask user for user pass
    user_password = getpass.getpass('Please enter your user pass:'******'\n' + bcolors.WARNING + '[+]' + bcolors.ENDC + ' .gdstartupdata UserKeyHash: ' + gdstartupdata[
        'UserKeyHash']
    print bcolors.WARNING + '[+]' + bcolors.ENDC + ' Calculate UserKeyHash: ' + b64encode(
        hashlib.sha512(generated_UserKeyHash).digest())

    if (gdstartupdata['UserKeyHash'] == b64encode(
            hashlib.sha512(generated_UserKeyHash).digest())):
        print bcolors.OKGREEN + 'Keys Match!' + bcolors.ENDC + '\n'
    else:
        print bcolors.FAIL + 'Keys DO NOT Match!' + bcolors.ENDC + '\n'
        print '[-] .DContainer decrypted.'
        print '[-] However, without the correct user key, the other containers cannot be decrypted.'
        quit()

    # =================================================
    # Get keys to decrypt FS
    # =================================================
    startupiv = b64decode(gdstartupdata['StartupIV'])

    # Encrypted Data Encryption Key, needs to be decrypted
    edek = b64decode(gdstartupdata['EncryptedMCKey'])
    dek = aes_cbc_decrypt(edek, startupiv, generated_UserKeyHash)[:32]
    print "[+] Data Encryption Key: " + dek.encode('hex')

    print '[+] Decrypting MContainer ...'
    shutil.copytree(encrypted_mcontainer, decrypted_mcontainer)

    for root, dirs, files in os.walk(decrypted_mcontainer):
        for d in dirs:
            orig_d = d
            d = b64_filename(d)

            if decode_base64(d)[0] == '\x02':
                folder_name = aes_cbc_decrypt(
                    decode_base64(d)[1:], startupiv, dek).strip()
            else:
                folder_name = aes_cbc_decrypt(decode_base64(d), startupiv,
                                              dek).strip()

            folder_name = filter(lambda x: x in string.printable, folder_name)
            os.rename(decrypted_mcontainer + '/' + orig_d,
                      decrypted_mcontainer + '/' + folder_name)

    for root, dirs, files in os.walk(decrypted_mcontainer):
        for f in files:
            orig_f = f
            f = b64_filename(f)

            try:
                if decode_base64(f)[0] == '\x02':
                    file_name = aes_cbc_decrypt(
                        decode_base64(f)[1:], startupiv, dek).strip()
                else:
                    file_name = aes_cbc_decrypt(decode_base64(f), startupiv,
                                                dek).strip()
            except:
                e = sys.exc_info()[0]

            try:
                file_name = filter(lambda x: x in string.printable, file_name)
                os.rename(os.path.join(root, orig_f),
                          os.path.join(root, file_name))

                new_file_path = os.path.join(root, file_name)

                data = decrypt_file(new_file_path, dek)
                data = filter(lambda x: x in string.printable, data)

                if (os.path.splitext(new_file_path)[1]
                        == '.cfg') or (os.path.splitext(new_file_path)[1]
                                       == '.data'):
                    try:
                        data = json.loads(data.strip())
                        data = json.dumps(data, indent=4)
                    except:
                        e = sys.exc_info()[0]

                f = open(new_file_path, 'w')
                f.write(data)
                f.close()
            except:
                e = sys.exc_info()[0]

    print '[+] Decrypting CContainer ...'
    shutil.copytree(encrypted_ccontainer, decrypted_ccontainer)

    for root, dirs, files in os.walk(decrypted_ccontainer):
        for d in dirs:
            orig_d = d
            d = b64_filename(d)

            if decode_base64(d)[0] == '\x02':
                folder_name = aes_cbc_decrypt(
                    decode_base64(d)[1:], startupiv, dek).strip()
            else:
                folder_name = aes_cbc_decrypt(decode_base64(d), startupiv,
                                              dek).strip()

            folder_name = filter(lambda x: x in string.printable, folder_name)
            os.rename(decrypted_ccontainer + '/' + orig_d,
                      decrypted_ccontainer + '/' + folder_name)

    for root, dirs, files in os.walk(decrypted_ccontainer):
        for f in files:
            orig_f = f
            f = b64_filename(f)

            try:
                if decode_base64(f)[0] == '\x02':
                    file_name = aes_cbc_decrypt(
                        decode_base64(f)[1:], startupiv, dek).strip()
                else:
                    file_name = aes_cbc_decrypt(decode_base64(f), startupiv,
                                                dek).strip()
            except:
                e = sys.exc_info()[0]

            file_name = filter(lambda x: x in string.printable, file_name)
            os.rename(os.path.join(root, orig_f),
                      os.path.join(root, file_name))

            new_file_path = os.path.join(root, file_name)

            data = decrypt_file(new_file_path, dek)
            data = filter(lambda x: x in string.printable, data)

            if (os.path.splitext(new_file_path)[1]
                    == '.cfg') or (os.path.splitext(new_file_path)[1]
                                   == '.data'):
                try:
                    data = json.loads(data.strip())
                    data = json.dumps(data, indent=4)
                except:
                    e = sys.exc_info()[0]

            f = open(new_file_path, 'w')
            f.write(data)
            f.close()
Example #33
0
 def make_key(username, password, iterations=1):
     if iterations == 1:
         return hashlib.sha256(username + password).digest()
     else:
         return pbkdf2.pbkdf2_bin(password, username, iterations, 32,
                                  hashlib.sha256)
Example #34
0
    elif sys.argv[1] == "k":
        mode = "0-in-xk"
    elif sys.argv[1] == "M":
        mode = "0-in-xM"
    else:
        raise ValueError("unknown mode '%s'" % sys.argv[1])

printheader("stretch-KDF")
emailUTF8 = u"andré@example.org".encode("utf-8")
passwordUTF8 = u"pässwörd".encode("utf-8")
printhex("email", emailUTF8)
printhex("password", passwordUTF8)

# stretching
time_start = time.time()
k1 = pbkdf2_bin(passwordUTF8, KWE("first-PBKDF", emailUTF8), 20 * 1000, keylen=1 * 32, hashfunc=sha256)
time_k1 = time.time()
printhex("K1 (scrypt input)", k1)
k2 = scrypt.hash(k1, KW("scrypt"), N=64 * 1024, r=8, p=1, buflen=1 * 32)
time_k2 = time.time()
printhex("K2 (scrypt output)", k2)
stretchedPW = pbkdf2_bin(k2 + passwordUTF8, KWE("second-PBKDF", emailUTF8), 20 * 1000, keylen=1 * 32, hashfunc=sha256)
time_k3 = time.time()
# print "stretching took %0.3f seconds (P=%0.3f + S=%0.3f + P=%0.3f)" % \
#      (time_k3-time_start,
#       time_k1-time_start, time_k2-time_k1, time_k3-time_k2)

printhex("stretchedPW", stretchedPW)


def findMainSalt(stretchedPW):
Example #35
0
 def make_key(cls, username, password, key_iteration_count):
     if key_iteration_count == 1:
         return hashlib.sha256(username + password).digest()
     else:
         return pbkdf2.pbkdf2_bin(password, username, key_iteration_count, 32, hashlib.sha256)
Example #36
0
def main():
    emailUTF8, passwordUTF8, command = sys.argv[1:4]
    assert isinstance(emailUTF8, binary_type)
    printhex("email", emailUTF8)
    printhex("password", passwordUTF8)

    k1 = pbkdf2_bin(passwordUTF8, KWE("first-PBKDF", emailUTF8),
                    20*1000, keylen=1*32, hashfunc=sha256)
    time_k1 = time.time()
    printhex("K1", k1)
    k2 = scrypt.hash(k1, KW("scrypt"), N=64*1024, r=8, p=1, buflen=1*32)
    time_k2 = time.time()
    printhex("K2", k2)
    stretchedPW = pbkdf2_bin(k2+passwordUTF8, KWE("second-PBKDF", emailUTF8),
                             20*1000, keylen=1*32, hashfunc=sha256)
    printhex("stretchedPW", stretchedPW)

    GET("__heartbeat__")

    if command == "create":
        mainKDFSalt = makeRandom()
        srpSalt = makeRandom()
    else:
        r = POST("session/auth/start",
                 {"email": #emailUTF8.encode("hex")
                  emailUTF8.encode("utf-8")
                  })
        print "auth/start", r
        srpToken = r["srpToken"]
        B = r["srp"]["B"].decode("hex")
        srpSalt = r["srp"]["s"].decode("hex")
        mainKDFSalt = r["stretch"]["salt"].decode("hex")
        # ignore stretch.rounds, srp.N_bits, srp.alg

    printhex("mainKDFSalt", mainKDFSalt)
    printhex("srpSalt", srpSalt)

    (srpPW, unwrapBKey) = split(HKDF(SKM=stretchedPW,
                                     XTS=mainKDFSalt,
                                     CTXinfo=KW("mainKDF"),
                                     dkLen=2*32))

    if command == "create":
        (srpVerifier, _, _, _, _) = mysrp.create_verifier(emailUTF8, srpPW,
                                                          srpSalt)

        r = POST("account/create",
                 {#"email": emailUTF8.encode("hex"), # TODO prefer hex
                     "email": emailUTF8.encode("utf-8"),
                  "verifier": srpVerifier.encode("hex"),
                  "salt": srpSalt.encode("hex"),
                  "params": {"srp": {"alg": "sha256", "N_bits": 2048},
                             "stretch": {"salt": mainKDFSalt.encode("hex"),
                                         "rounds": 20000}
                             },
                  })
        print r
    else:
        srpClient = mysrp.Client()
        A = srpClient.one()
        M1 = srpClient.two(B, srpSalt, emailUTF8, srpPW)
        r = POST("session/auth/finish",
                 {"srpToken": srpToken,
                  "A": A.encode("hex"),
                  "M": M1.encode("hex")})
        print "auth/finish:", r
        bundle = r["bundle"].decode("hex")
        print "bundlelen", len(bundle)

        # note: the server is not yet using the new protocol. The old one
        # returns keyFetchToken+sessionToken
        if 1: # old protocol
            x = HKDF(SKM=srpClient.get_key(),
                     dkLen=3*32,
                     XTS=None,
                     CTXinfo=KW("session/auth"))
            respHMACkey = x[0:32]
            respXORkey = x[32:]
            ct,respMAC = bundle[:-32], bundle[-32:]
            respMAC2 = HMAC(respHMACkey, ct)
            printhex("respHMACkey", respHMACkey)
            printhex("respXORkey", respXORkey)
            printhex("ct", ct)
            assert respMAC2 == respMAC, (respMAC2.encode("hex"),
                                         respMAC.encode("hex"))
            keyFetchToken, sessionToken = split(xor(respXORkey,ct))

        if 0: # new protocol
            authToken = getAuthToken(srpClient.get_key())
            x = HKDF(SKM=srpClient.get_key(),
                     dkLen=2*32,
                     XTS=None,
                     CTXinfo=KW("auth/finish"))
            respHMACkey = x[0:32]
            respXORkey = x[32:]
            ct,respMAC = bundle[:-32], bundle[-32:]
            respMAC2 = HMAC(respHMACkey, ct)
            assert respMAC2 == respMAC, (respMAC2.encode("hex"),
                                         respMAC.encode("hex"))
            authToken = xor(ct, respXORkey)
            printhex("authToken", authToken)
            keyFetchToken, sessionToken = createSession(authToken)

        printhex("keyFetchToken", keyFetchToken)
        printhex("sessionToken", sessionToken)

        kA,kB = getKeys(keyFetchToken, unwrapBKey)
        printhex("kA", kA)
        printhex("kB", kB)
Example #37
0
def get_key_and_iv(passphrase, salt):
    keyiv = pbkdf2_bin(passphrase, salt,
                       iterations = HASH_COUNT, keylen = 32)
    key = keyiv[0:KEY_LEN_BYTES]
    iv = keyiv[KEY_LEN_BYTES:IV_LEN_BYTES+KEY_LEN_BYTES]
    return key, iv