How to decrypt sha1-encrypted String in Java

2019-02-12 19:57发布

问题:

Is it possible to decrypt some string which was earlier encrypted with the SHA-1 algorithm in Java?

回答1:

SHA1 is a cryptographic hash function, and the entire point is that you can't undo it. If it was possible to reverse the hash (find the input for a given hash), it wouldn't be useful. If you need to encrypt something and later decrypt it, you should use an encryption function like AES or RSA.

However, for very simple inputs it may be possible to crack the hash function by guessing what the input was and checking if the hash is the same.

Example Python code:

def crack_hash(hash_to_crack, hash_function, list_of_guesses):
    # Try to hash everything in our guess list
    for guess in list_of_guesses:
        new_hash = hash_function(guess)
        # if the hashes match, we found it
        if new_hash == hash_to_crack:
            return guess
    # If none of them match, give up
    return None

Of course, if you actually want to crack hashes efficiently, using software like John the Ripper or Hashcat is probably your best bet. Note that this usually works on passwords since they're short and easy to guess, but the difficulty increases exponentially as the input increases. You can crack every SHA-1 hash with a 6-character input in minutes, while cracking one with 16 characters would take trillions of years on average.



回答2:

No, this is not possible, because SHA-1 is a hash - it's a one way ticket. If you want to crypt and decrypt a string then you'll need to use some encryption algorithm that uses key to generate encrypted data. Then you can encrypt data and after successfully decrypt it. For example AES. You can read about AES from here



回答3:

Short answer: it's impossible.

Because SHA-1 is a cryptographic hash function, by the pigeonhole principle, it is mathematically impossible to reverse. There are only 2160 possible SHA-1 hashes. Since there are an infinite number of possible input strings, there must be collisions (multiple inputs that hash to the same value). In general, there's no way you can know which of those strings was the original input.

However, real-world strings aren't completely arbitrary. If you know some information about your input string (e.g. that it was less than 5 characters long), with high probability, the input is unique. Unfortunately for you, hash functions like SHA-1 are intentionally computationally infeasible to invert. (There are theoretical attacks on SHA-1, but I don't think any are currently considered even near feasible.)

So if you need to recover hashed data, you have to use brute force: try SHA-1ing each string of length less than n, and see if the hash matches. But there are exponentially many strings of length up to n, so this quickly becomes infeasible.

There is one possible way to recover hashed data before the end of the universe. Your only hope is to use a more sophisticated method, such as rainbow tables. This will only work if you know that your original string was very short (less than ~15 characters). Even for short strings, it will take a long time (and gigabytes of disk space) to pre-compute the table.