Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I've looked on this site and on SE. but i couldn't get a handle on this. Is there a way to find what type of encryption/encoding is being used? For example, I am testing a web application which stores the password in the database in an encrypted format. WeJcFMQ/8+8QJ/w0hHh+0g== How do i determine what hashing or encryption is being used? Or is there a way?

share|improve this question
2  
Some content of (or links pointing to) a methodology is in order to explain how to identify certain types of crypto or encoding in a completely zero-knowledge scenario. Most of these answers are "it's impossible" and my gut feeling tells me that nothing in our industry is impossible. –  atdre May 23 '11 at 14:28
    
@atdre Thanks for the bounty. The question seems focussed on password hashing formats - is that your focus also? That seems best to me, and if people want to answer the question for file formats, they can ask another question. –  nealmcb May 23 '11 at 15:44
    
@atdre: "Impossible" is usually a shortcut for "infeasible with current technology/won't finish before the heat death of the universe". –  Piskvor May 23 '11 at 17:13
    
@nealmcb: Identification of encrypted or encoded non-plaintext. –  atdre May 24 '11 at 15:46
1  
I asked a similar question on SE: stackoverflow.com/questions/988642/… –  Alexandru Luchian Oct 25 '11 at 17:48

8 Answers 8

up vote 42 down vote accepted
+100

Your example string (WeJcFMQ/8+8QJ/w0hHh+0g==) is Base64 encoding for a sequence of 16 bytes, which do not look like meaningful ASCII or UTF-8. If this is a value stored for password verification (i.e. not really an "encrypted" password, rather a "hashed" password) then this is probably the result of a hash function computed over the password; the one classical hash function with a 128-bit output is MD5. But it could be about anything.

The "normal" way to know that is to look at the application code. Application code is incarnated in a tangible, fat way (executable files on a server, source code somewhere...) which is not, and cannot be, as much protected as a secret key can. So reverse engineering is the "way to go".

Barring reverse engineering, you can make a few experiments to try to make educated guesses:

  • If the same user "changes" his password but reuses the same, does the stored value changes ? If yes, then part of the value is probably a randomized "salt" or IV (assuming symmetric encryption).
  • Assuming that the value is deterministic from the password for a given user, if two users choose the same password, does it result in the same stored value ? If no, then the user name is probably part of the computation. You may want to try to compute MD5("username:password") or other similar variants, to see if you get a match.
  • Is the password length limited ? Namely, if you set a 40-character password and cannot successfully authenticate by typing only the first 39 characters, then this means that all characters are important, and this implies that this really is password hashing, not encryption (the stored value is used to verify a password, but the password cannot be recovered from the stored value alone).
share|improve this answer
    
Thanks for the inputs.. Pls tell me more about how you confirmed its a Base64 encoding for a sequence of 16 bytes. Regarding your experiments, Yes, this is a value stored for password verification. 1) if a user changes password, then the stored value changes too.. 2) if two users choose same password, the stored value is the same 3) password length is not limited. –  Karthik May 27 '11 at 10:28
5  
@Learner: any sequence of 24 characters, such that the first 22 are letters, digits, '+' or '/', and the last two are '=' signs, is a valid Base64 encoding of a 128-bit value. And any 128-bit value, when encoded with Base64, yields such a sequence. –  Thomas Pornin May 27 '11 at 12:21
1  
This is the right answer, even though I wanted to hear some potential tricks if the application code isn't available. If you are dealing with a closed-source binary application -- check out aluigi.org/mytoolz.htm#signsrch –  atdre May 29 '11 at 16:19
    
If it is MD5 you could try any of the MD5 cracking websites like md5decrypter.co.uk. None of these are fast or guaranteed to give a result. Google for "md5 cracking" to find more. That will also give you an extendeed list at stottmeister.com/blog/2009/04/14/how-to-crack-md5-passwords –  Jan Doggen Feb 26 '13 at 15:41

Edit: I just noticed a very cool script named 'Hash Identifier" http://code.google.com/p/hash-identifier/ The name pretty much describes it.

~~~

Generally speaking, using experience to make educated guesses is how these things are done.

Here is a list with a very big number of hash outputs so that you know how each one looks and create signatures/patters or just optically verify.

There are two main things you first pay attention to:

  • the length of the hash (each hash function has a specific output length)
  • the alphabet used (are all english letters? numbers 0-9 and A-F so hex? what special characters are there if any?)

Several password cracking programs (John the ripper for example) apply some pattern matching on the input to guess the algorithm used, but this only works on generic hashes. For example, if you take any hash output and rotate each letter by 1, most pattern matching schemes will fail.

share|improve this answer
    
thank you.. i took a look and tried with few passwords. but the method works given the scenario we know the password is hashed and not encrypted, right? –  Karthik May 27 '11 at 9:27
1  
Passwords are usually not encrypted, they are hashed, and usually represented inthe form the function outputs them - so you can find many of those forms in the links above. In the end, the output of all functions is just binary digits which are usually represented and stored either as the hex representation, or as the base64 representation. –  john May 27 '11 at 16:32

What you have posted is 16 bytes (128 bits) of base 64 encoded data. The fact that it is base 64 encoded doesn't tell us much because base 64 is not an encryption/hashing algorithm it is a way to encode binary data into text. This means that this block includes one useful piece of information, namely that the output is 16 bytes long. We can compare this to the block size of commonly used schemes and figure out what it can't be. By far the most common schemes are:

The next thing we need to do is to look at other blocks of cipher text to figure out the answer to the following question:

  • Are all cipher texts the same length, even for different input lengths?

If not all blocks are the same length then you aren't looking at a hashing algorithm, but an encryption one. Since the output will always be a multiple of the underlying block size the presence of a block that is not evenly divisible by 16 bytes would mean that it cant be AES and therefore must be DES or 3DES.

If you have the ability to put in a password and observe the output this can be determined very quickly. Just put in a 17 character password and look at the length. If its 16 bytes you have MD5, 20 bytes means SHA-1, 24 bytes means DES or 3DES, 32 bytes means AES.

share|improve this answer
    
:-p i don't get it.. is it a base 64 encoded data?? how? and i definitely didn't get the part where you say "if any blocks are not evenly divisible by 16 bytes it is probably DES or 3DES, otherwise AES most likely" pls shed me some light on this. :) –  Karthik May 27 '11 at 9:41
    
@The Learner I've added to the answer to hopefully make it clearer. If you can use chosen plaintext you can probably work it out from this. –  Yaur May 27 '11 at 10:04
    
thank you so much.. i'm starting to get the second part. and after asking this question here, i read somewhere in google that hashing is many-to-one, meaning that many different texts could be hashed to a same output (pls correct me if i am wrong). –  Karthik May 27 '11 at 11:26
    
thank you so much.. i'm starting to get the second part. and after asking this question here, i read somewhere in google that hashing is many-to-one, meaning that many different texts could be hashed to a same output (pls correct me if i am wrong). coming to our scenario, all the cypher text blocks are not of same length.. so now can i be sure that they are not hashed but encrypted? But still, i didn't get how you said that the data i posted is 16 bytes of base 64 encoded data. If there is a cypher or hash, how would i tell that it is a 16 or 32 byte data? –  Karthik May 27 '11 at 11:31
2  
@the learner the = as padding is characteristic of base64. This tool home2.paulschou.net/tools/xlate (from a google search on base64 decoder hex) will convert from base 64 to an array of hex values. just paste your text into the base 64 box and click decode and count the bytes. you can also estimate by taking the number of characters in the base64 string and multiplying by .75 –  Yaur May 27 '11 at 11:41

The only way is to guess. With experience, guess works will be more correct.

For example: Based on length of output: MD5 output is 128 bits, or 16 bytes, SHA1 output is 160 bits, or 20 bytes. Based on charset of output: BASE64 produces output with printable characters.

At the end of the day, it's the try-and-error approach that teaches you how.

share|improve this answer

It depends upon the format - some protocols for storing encrypted text have a cleartext portion that defines how it's encrypted. From your example, I'm doubtful since the string you reference is so short that it looks like it's just the encrypted text.

I'd suggest a couple thoughts:

  • The "==" on the end would definitely be padding, so don't include that in any decryption attempts.

  • You may be dealing with a hash or a salted hash, rather than encryption. In that case, trying to "decrypt" the data won't work - you need to match passwords by using the same hash and/or salt value that was used originally. There is no way with a salted password to get the original value.

  • Your absolute best bet is to get a copy of the code that is used to store the passwords. Somewhere in there, the passwords are undergoing a cryptographic operation. Find the code to learn what's happening here. 9 times out of 10, they are using some sort of API for the hashing/salting/encryption and you can imitate or reverse it using the same API.

share|improve this answer
    
The == on the end is a tell-tale sign of the value being base64 encoded. The padding is necessary; you don't just drop it. First you base64-decode the data, THEN play with it. –  tylerl Jun 19 '13 at 16:45

Encoding can generally be guessed at. For example, the string you posted in your question is Base64 encoded. The equals signs are padding in the Base64 scheme. That's something I know on-sight from experience.

If you gave me a string that was encrypted, I may be able to tell you the encoding but I can't tell you the algorithm used to encrypt it unless some sort of metadata is available. The reason is this: encryption algorithms work by producing what appears to be random data. If I encrypted two sentences each with two ciphers (four outputs), you would be unable to tell me with any confidence which ciphertext belonged to which cipher unless you decrypted it or broke the cipher.

In regards to your specific instance, passwords are usually hashed. That means you can't recover the password from the hash, but you can test to see if the hash matches for the password. In that regard, @john's answer is golden. If you can input a password that you know and then try common schemes against it, you can learn what the hash used is.

share|improve this answer

The only way is when there's some metadata that tells you. For instance, I've been working with PDFs lately, and the format includes a dictionary containing the filter, algorithm, key size etc. But if all you've got is the ciphertext, then all you've got is some opaque blob of data.

share|improve this answer

If this is indeed a simple password hash, we might be able to use Google to crack it. Base64 is hard to search for, though, with all those slashes and plus signs, so let's first convert that hash into hexadecimal:

$ perl -MMIME::Base64 -le 'print unpack "H*", decode_base64 "WeJcFMQ/8+8QJ/w0hHh+0g=="'
59e25c14c43ff3ef1027fc3484787ed2

OK, now we can Google for it. At the moment, I'm getting only one hit, from md5this.com — although obviously there will quite soon be more, including this post.

Unfortunately (or perhaps fortunately, depending on your perspective), we're not lucky enough to actually find a preimage (the site currently lists this hash as "cracking..."), but the fact that it's on that list at all does strongly suggest that it's indeed an unsalted MD5 hash of a real password.

share|improve this answer

protected by Jeff Ferland Jun 18 '13 at 21:51

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.