Cracking passwords with DES algorithm given hash and salt - python

I am given a hash ("1u9Tc6HX") and the salt ("Ff"), and I am told to crack the password knowing that it has been hashed with DES algorithm. Using hashcat, I have known that the password is ("michael") and I am now trying to hash this password in order to compare it with the hash given.
However, I have tried using (openssl enc) command but it always asks me for the password used for encryption, what I am not given, so I don't know how to hash ("michael") using DES and salt ("Ff") and get ("1u9Tc6HX"). I am open to change the procedure and try other things in case you think is easier to crack by other way. (I am working with python)
Any comment and help is appreciated.
Pd:
Example: Ff1u9Tc6HXxJo
Enunciate: The password has been hashed using the DES algorithm. The entry consists
in 13 printable ASCII characters, where the two first characters represent the salt.
With DES, only the first 8 characters of the password are used.

Passlib is a popular library for password hashing:
>>> import passlib.hash
>>> passlib.hash.des_crypt.hash('michael', salt='Ff')
'Ff1u9Tc6HXxJo'

Related

Encoding user Input to get an encryption key

I am taking in user input and need to turn it into an AES encryption key.
I have:
keyInput= input("Enter key:")
key = keyInput.encode()
print(key)
If I type in "computer" for the input. I get the result b'computer' for the output.
Shouldn't it look something more like this?
b'\xbf\xc0\x85)\x10nc\x94\x02)j\xdf\xcb\xc4\x94\x9d(\x9e[EX\xc8\xd5\xbfI{\xa2$\x05(\xd5\x18'
"computer" cannot be an AES key because it only consists of ASCII characters. Keys for algorithms such as AES should consist of fully randomized bits and of course of a specific size (128, 192 or 256 bits).
What you are after is password based encryption. For this there are standards, such as PKCS#5, literally the "Password-Based Cryptography Specification" (Version 2.1). Basically it uses PBKDF2 to calculate a key from a relatively weak password using a salt and a work factor (or, in the case of PBKDF2, an iteration count).
Long answer: https://crypto.stackexchange.com/questions/53552/aes-with-small-and-large-string-keys
Short answer. AES takes a 128-bit, 192-bit, or 256-bit key. Some APIs let you use a password instead of a key. How the password gets converted into the appropriate length key is not part of the AES standard. There are a large number of "Password Based Key Derivation Functions" (PBKDF) that perform this function.

How to decrypt a password des(unix) with 13 string with python

Here my decode a password with 13 string
U5IhmemtXSSA. ===> admin
G1Cbobnlhh9xA ===> flower
What function or code should I use to decode a password like that?
as your title says it's a Unix style crypt (salted) password hash. to verify under Python you can do:
from crypt import crypt
print(crypt('admin', 'U5'))
and you'll get U5IhmemtXSSA. back.
cryptographic hashes can't be "decrypted" in the traditional sense, but you can enumerate possible inputs to find out which ones result in the same hash. as suggested by #schlenk you could try hashcat or you could try something like john the ripper to quickly do this.

Safer way to remove salt from a decrypted key

I have a decrypted key that is salted with random special characters (it's been changed): J_a&3#000$0=f%4{4-f-1*1(1-d#0-3&e|0)1&987*5(b#123$1'1(4*0)1}c+f'59#d#8_6_c)4#1#c(3} I need to remove all the special characters and return the unsalted version of it, for example, right now I'm using:
def remove_salt(decrypted_key):
""" Remove salt from a decrypted key """
invalid_chars = set(string.punctuation)
return_key = []
for c in decrypted_key:
if c not in invalid_chars:
return_key.append(c)
return ''.join(return_key)
So it would look like this:
>>> remove_salt("J_a&3#000$0=f%4{4-f-1*1(1-d#0-3&e|0)1&987*5(b#123$1'1(4*0)1}c+f'59#d#8_6_c)4#1#c(3}")
'Ja30000f44f111d03e019875b12311401cf59d86c41c3'
>>>
Is there a safer way that I can remove the salt from the key without completely revealing what the salt is, what I mean is string.punctuation clearly states, that invalid characters are !##$ .. etc. How can I remove this salt without completely revealing what my salt is?
Please note, the way this is salted was not my choice. I just need to get this thing unsalted without it being super noticeable as to what the salt is.
I am confused with your use of salt. Salt is typically appended at the beginning or end of a password, and the result encrypted and stored. Salt values themselves are stored in the clear, and are use mainly to make dictionary attacks more difficult. So, when a user enters their password, you retrieve their designated salt from wherever you have stored it, append it to what they have entered, hash it with whatever password hash you have chosen, and check to see if the stored hash matches the provided hash. Perhaps some clarification is in need - why are you trying to remove a salt that is embedded in the password?

Why can bcrypt.hashpw be used both for hashing and verifying passwords?

Using bcrypt with Python 2.7, I can see that the example uses the bcrypt.hashpw to both hash a password for storage and verify that the given password matches a hashed one, like so:
Hashing
import bcrypt
password = b"somepassword"
hashed = bcrypt.hashpw(password, bcrypt.gensalt())
Ok, so far so good. The given password is now hashed using bcrypt, so it is a string of hashed bytes.
Verifying
Now, here's the part that confuses me: to check that a plaintext password matches a hashed password, the same function is used, using the hashed password as a salt:
if bcrypt.hashpw(password, hashed) == hashed:
print("It Matches!")
else:
print("It Does not Match :(")
What's happening?
Shouldn't the results of both bcrypt.hashpw calls be different, since the input salts are different?
The only reasonable answer I can think of is that the salt is truncated to a fixed length before being prepended to the hashed password. That way, when using the result of the hash, only the generated salt is left (after stripping off the trailing hashed password), and the result of hashing the password with the truncated salt is the same as the original. I don't have any evidence to support this, though.
Why does this work?
In the expression bcrypt.hashpw(password, hashed) only the first couple of characters of hashed are used for the salt, not the entire string.
For instance, in this example how the output of hashpw() begins with the salt:
salt1 = b"$2a$12$w40nlebw3XyoZ5Cqke14M."
print "salt1:", salt1
print "hash1:", bcrypt.hashpw(password, salt1)
prints:
salt1: $2a$12$w40nlebw3XyoZ5Cqke14M.
hash1: $2a$12$w40nlebw3XyoZ5Cqke14M.d.7cdO2wJhr/K6ZSDjODIxLrPmYzY/a
so there is a convention where the salt only goes up the first period or the first 29 characters.
The hashpw function returns the salted hash (iterated many times, following bcyrpt spec), preceeded by the salt used (and with a dot as seperator).
In : salt = bcrypt.gensalt()
In : all(salt == bcrypt.hashpw(pw,salt)[:len(salt)] for pw in ('','12345','asdfgh'))
Out: True
If the second argument to bcrypt.hashpw is recognized as of the form VALID_SALT.VALID_HASH, then the salt is automagically set to VALID_SALT, thus producing the same salt-hash-pair as the original password on identical pw input.

How to hash strings in Python?

I have code that outputs all possible combinations of characters from a given character list as follows:
def charList():
charSet = string.ascii_letters + string.digits
for wordchars in product(charSet, repeat=8):
print(''.join(wordchars))
Now I need to turn the output strings into a DES hash then compare the output to user input to see if any matches are found.
Have been doing some research and haven't made much progress. So wondering if anyone on here could help?
If you want to hash strings (and not encrypt them), you can use the built-in hashlib module:
>>> import hashlib
>>> m = hashlib.md5()
>>> m.update("Nobody inspects")
>>> m.update(" the spammish repetition")
>>> m.digest()
'\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9'
EDIT: as said in the comments, prefer hashlib.sha256() which is far more secured today.
Quick search for DES and Python gave me these libraries:
http://pypi.python.org/pypi/pycrypto/2.6
http://packages.python.org/passlib/lib/passlib.hash.des_crypt.html
http://docs.python.org/2/library/crypt.html
Platforms: Unix
This module implements an interface to the crypt(3) routine, which is
a one-way hash function based upon a modified DES algorithm; see the
Unix man page for further details. Possible uses include allowing
Python scripts to accept typed passwords from the user, or attempting
to crack Unix passwords with a dictionary.
Notice that the behavior of this module depends on the actual
implementation of the crypt(3) routine in the running system.
Therefore, any extensions available on the current implementation will
also be available on this module
crypt.crypt(word, salt)
word will usually be a user’s password as typed at a prompt or in a
graphical interface. salt is usually a random two-character string
which will be used to perturb the DES algorithm in one of 4096 ways.
The characters in salt must be in the set [./a-zA-Z0-9]. Returns the
hashed password as a string, which will be composed of characters from
the same alphabet as the salt (the first two characters represent the
salt itself).
Since a few crypt(3) extensions allow different values, with different
sizes in the salt, it is recommended to use the full crypted password
as salt when checking for a password.
A simple example illustrating typical use:
import crypt, getpass, pwd
def login():
username = raw_input('Python login:')
cryptedpasswd = pwd.getpwnam(username)[1]
if cryptedpasswd:
if cryptedpasswd == 'x' or cryptedpasswd == '*':
raise NotImplementedError(
"Sorry, currently no support for shadow passwords")
cleartext = getpass.getpass()
return crypt.crypt(cleartext, cryptedpasswd) == cryptedpasswd
else:
return 1

Categories

Resources