I'm using the first 6 characters of an MD5 hashed string to use for displaying a color.
ie:
"hello world".Md5().Substring(0, 6);
There is a certain instance in my application where I need a certain color. I want to feed data that I know will provide a certain character pattern (in my case FF0000).
So is there a way to.. reverse generate an MD5? Or a good way of brute building MD5s to produce an MD5 hash that starts out in FF0000?
If this is impossible, I can hardcoded this exception into the application, however the least amount of "hacks" required, the better.
Thanks!
You cannot reverse an MD5 as it's a one way function. But we can try candidates until we find one that we like.
Here is a small program that increments a counter and test that counter as a string for md5 hash.
It takes a few seconds and 2 million tries to find an md5 starting with FF0000.
Python 3:
import hashlib
target = 'ff0000'
candidate = 0
while True:
plaintext = str(candidate)
hash = hashlib.md5(plaintext.encode('ascii')).hexdigest()
if hash[:6] == target:
print('plaintext:"' + plaintext + '", md5:' + hash)
break
candidate = candidate + 1
Result:
plaintext:"2237563", md5:ff0000475d94089c1f6c3fb9e19a8015
Related
I am trying to implement a Direct Connect Client, and I am currently stuck at a point where I need to hash the files in order to be able to upload them to other clients.
As the all other clients require a TTHL (Tiger Tree Hashing Leaves) support for verification of the downloaded data. I have searched for implementations of the algorithm, and found tiger-hash-python.
I have implemented a routine that uses the hash function from before, and is able to hash large files, according to the logic specified in Tree Hash EXchange format (THEX) (basically, the tree diagram is the important part on that page).
However, the value produced by it is similar to those shown on Wikipedia, a hex digest, but is different from those shown in the DC clients I'm using for reference.
I have been unable to find out how the hex digest form is converted to this other one (39 characters, A-Z, 0-9). Could someone please explain how that is done?
Well ... I tried what Paulo Ebermann said, using the following functions:
def strdivide(list,length):
result = []
# Calculate how many blocks there are, using the condition: i*length = len(list).
# The additional maths operations are to deal with the last block which might have a smaller size
for i in range(0,int(math.ceil(float(len(list))/length))):
result.append(list[i*length:(i+1)*length])
return result
def dchash(data):
result = tiger.hash(data) # From the aformentioned tiger-hash-python script, 48-char hex digest
result = "".join([ "".join(strdivide(result[i:i+16],2)[::-1]) for i in range(0,48,16) ]) # Representation Transform
bits = "".join([chr(int(c,16)) for c in strdivide(result,2)]) # Converting every 2 hex characters into 1 normal
result = base64.b32encode(bits) # Result will be 40 characters
return result[:-1] # Leaving behind the trailing '='
The TTH for an empty file was found to be 8B630E030AD09E5D0E90FB246A3A75DBB6256C3EE7B8635A, which after the transformation specified here, becomes 5D9ED00A030E638BDB753A6A24FB900E5A63B8E73E6C25B6. Base-32 encoding this result yielded LWPNACQDBZRYXW3VHJVCJ64QBZNGHOHHHZWCLNQ, which was found to be what DC++ generates.
The only mention of the format of the hash in the Direct Connect protocol I found is on the $SR page on the NMDC Protocol wiki:
For files containing TTH, the <hub_name> parameter is replaced with TTH:<base32_encoded_tth_hash> (ref: TTH_Hash).
So, it is Base32-encoding. This is defined in RFC 4648 (and some earlier ones), section 6.
Basically, you are using the capital letters A-Z and the decimal digits 2 to 7, and one base32 digit represents 5 bits, while one base16 (hexadecimal) digit represents only 4 ones.
This means, each 5 hex digits map to 4 base32-digits, and for a Tiger hash (192 bits) you will need 40 base32-digits (in the official encoding, the last one would be a = padding, which seems to be omitted if you say that there are always 39 characters).
I'm not sure of an implementation of a conversion from hex (or bytes) to base32, but it shouldn't be too complicated with a lookup table and some bit-shifting.
I have been researching but I am clueless.
I know that MD5 can have both numbers and letters but if I ever find a case where an MD5 has only numbers or only letters it breaks my script currently
List of few first strings that give only-digit md5 hash:
ximaz : 61529519452809720693702583126814
aalbke : 55203129974456751211900188750366
afnnsd : 49716523209578759475317816476053
aooalg : 68619150135523129199070648991237
bzbkme : 69805916917525281143075153085385
Here's one with only letters:
cbaabcdljdac : cadbfdfecdcdcdacdbbbfadbcccefabd
You have 32 digits. If we assume all ciphers equally distributed, there are 10^32 combinations, just made of numeric ciphers, 6^32 combinations of just alphabetic ciphers, and 16^32 combinations in total.
Which makes a (10^32 + 6^32) / 16^32 probability that your script will fail, on each invocation.
echo "scale=10;(10^32 + 6^32) / 16^32" | bc
.0000002938
So once in about 3.4 million cases it will fail. How often do you want to use it?
Theoretically, yes, an MD5 hash (when converted to a hexadecimal string) could contain only decimal digits or only letters.
In practice, also yes: the string ximaz yields an MD5 hash of 61529519452809720693702583126814. Try it!
(Thanks to PHP Sadness for the example)
MD5 was intended to be a good hash function (currently broken, should not be used security applications) which means that it produces random looking output so that all possible values that fit into output space are utilized. Those letters and numbers are hex representation of the output. Yes, sometimes you could get output that consists of letters only or numbers only, but most of the time you will have both.
If I had to parse hex representations of MD5 I would surely take time to support those rather rare cases when output is letters only or numbers only.
I know this is a very old question, but I found three more strings with only numbers in their md5 hashes, and Google couldn't find anything while searching these hashes so I thought it might be worth posting these:
Ioktak : 54948232518148653519995784773259
'99x\`b0x\'b : 24034969117462298298932307218853
uttuJ## : 74616072929762262275291990931711
I believe you are working with the hex representation of the MD5 hashes. MD5 hashes are actually 128-bit strings. Most tools print them with the hex-representation which amounts to 32 hexadecimal digits. Hexadecimal digits use 0-9 and a-f.
Example:
susam#swift:~$ echo -n "foo" | md5sum
acbd18db4cc2f85cedef654fccc4a4d8 -
I'm trying to verify salted passwords with Perl and am stuck with unpack.
I've got a salted hashed password, e.g. for SHA256: SSHA256 = SHA256('password' + 'salt') + 'salt'
Base64 encoded that gets '
{SSHA256}eje4XIkY6sGakInA+loqtNzj+QUo3N7sEIsj3fNge5lzYWx0'.
I store this string in my user database. When a user logs in need to separate the salt from the hash to hash the supplied password with the salt and compare the result to the one retrieved from the db. This is where I'm stuck. I don't seem to have the right unpack template separate the hash (8-bit binary, fixed length, in this case 32 byte) from the salt (8-bit binary, variable length).
I have tried something like
my ($hash, $salt) = unpack('N32 N*', $data);
but that doesn't seem to work out.
My question is: How can I unpack this hash (after it has been Base64 decoded) to get the fixed length hash in one and the variable length salt in another variable?
I think you're needlessly re-inventing the wheel.
You could use e.g. Crypt::SaltedHash to easily verify it, for instance:
my $password_entered = $cgi->param('password');
my $valid = Crypt::SaltedHash->validate($salted, $password_entered);
A longer example, showing using Crypt::SaltedHash to generate the salted password in the first instance, too:
my $csh = Crypt::SaltedHash->new(algorithm => 'SHA-256');
$csh->add('secretpassword');
my $salted = $csh->generate;
# $salted will contain the salted hash (Crypt::SaltedHash picks random
# salt for you automatically)
# for example:
DB x $salted = $csh->generate;
0 '{SSHA256}H1WaxHcyAB81iyIPwib/cCUtjqCm2sxQNA1QvGeh/iT3m51w'
# validating that against the plaintext 'secretpassword' shows it's right:
DB x Crypt::SaltedHash->validate($salted, 'secretpassword');
0 1
# and trying it with an incorrect password:
DB x Crypt::SaltedHash->validate($salted, 'wrongpassword');
0 ''
No reason to re-invent all of this yourself.
You seem to be doing RFC2307 the hard way and also manage to introduce bugs. Those + do not mean what you think.
Subclass Authen::Passphrase::SaltedDigest instead.
Not sure the whole picture is present, but the unpack template you have specified -'N32 N*'- is for 32 unsigned long (32-bit) (big-endian) integers (see pack docs).
Looks like you may instead need unsigned chars: '32C C*'
Assume I have two strings (or byte arrays) A and B which both have the same hash (with hash I mean things like MD5 or SHA1). If I concatenate another string behind it, will A+C and B+C have the same hash H' as well? What happens to C+A and C+B?
I tested it with MD5 and in all my tests, appending something to the end made the hash the same, but appending at the beginning did not.
Is this always true (for all inputs)?
Is this true for all (well-known) hash functions? If no, is there a (well-known) hash function, where A+C and B+C will not collide (and C+A and C+B do not either)?
(besides from MD5(x + reverse(x)) and other constructed stuff I mean)
Details depend on the hash function H, but generally they work as follows:
Consume a block of input X (say, 512 bits)
Break the input into smaller pieces (say, 32 bits) and update hash internal state based on the input
If there's more input, go to step 1
At the end, spit the internal state out as the hash value H(X)
So, if A and B collide i.e. H(A) = H(B), the hash will be in the same state after consuming them. Updating the state further with the same input C can make the resulting hash value identical. This explains why H(A+C) is sometimes H(B+C). But it depends how A's and B's sizes are aligned to input block size and how the hash breaks the input block internally.
C+A and C+B can be identical if C is a multiple of the hash block size but probably not otherwise.
This depends entirely on the hash function. Also, the probability that you have those collisions is really small.
The hash functions being discussed here are typically cryptographic (SHA1, MD5). These hash functions have an Avalanche effect -- the output will change drastically with a slight change in the input.
The prefix and suffix extension of C will effectively make a longer input.
So, adding anything to the front or rear of the input should change the effective hash outputs significantly.
I do not understand how you did the MD5 check, here is my test.
echo "abcd" | md5sum
70fbc1fdada604e61e8d72205089b5eb
echo "0abcd" | md5sum
f5ac8127b3b6b85cdc13f237c6005d80
echo "abcd0" | md5sum
4c8a24d096de5d26c77677860a3c50e3
Are you saying that you located two inputs which had the same MD5 hash and then appended something to the end or beginning of the input and found that adding at the end resulted in the same MD5 as that for the original input?
Please provide samples with your test results.
We have to automatically import a large list of users with some data into a running system.
For an initial password I want to update the list (csv format at the moment) with a random alphanumeric key (8 digits).
When inserting it with a special routine (which needs a csv file), the password (in this case the alphanumeric key) is stored as a md5 hash.
i.e. I generate a random alphanumeric key:
H2A5D39A -> MD5: 1642fccf791f15d137cf31282af79752
This way I want to create a list where authenticated users can ask me for their initial password (the alphanumeric key).
Do you have a better idea for a "secret" initial password?
How would you create the alphanumeric key in Perl?
P.S.: The "running system", not programmed by us, just allowes alphanumeric passwords (no special chars,...)
How would you create the alphanumeric key in Perl?
join'', map +(0..9,'a'..'z','A'..'Z')[rand(10+26*2)], 1..8
I would probably use pwgen. It is great as it allows easy customization, and has the switch not to use ambiguous characters (think: I, l, 1, O, 0).
for example:
=> pwgen -c -n -B 8 50
shuFak9o peiCh3Oo ohPieng9 Vohh7zuu os3Theep aeV9nuo9 aexeik4B aeChoh9s
uth3eePu baePhu3o aiS3pahn iPie4itu We9zuphi xie3Chi3 yeiRoo7c fai3ITai
aCh9ohco Echuab7v Fu9ahCho Aevae4no Peethai9 AiJio3Pa aeNge9Fo baePh7Uy
Nai7shei eeMoh9en Zeibai4n eGe7yuch Jaek7nai aeZah7sh Chei4ua4 shoo9oG9
iu7Wohho aep7De4U Fong9fo3 AhneeP7U oxae7Yoh ahF4eim3 fahm9Aiw naoNg4ie
Chie4xua jix3Uvot aChei7ai diey4Shi Yur7ee4j eeJeo9ee Bou3ahmu kaeb4Cah
Eh4Eemae oD4phoo9
Anonymous's answer is very good, but, if you need a random string that conforms to some rules (such as at least one uppercase, one lowercase, and one number), you may want to look into String::Random.
Another module to consider is Data::Random
I just completed a review of the 12 modules on CPAN that can be used to generate random passwords:
http://blogs.perl.org/users/neilb/2011/08/random-password-generation.html
In short: if you want a pronounceable password, look at Crypt::YAPassGen,
otherwise go for App::Genpass.
App::Genpass avoids confusable characters and gives you better control (and defaults) than Data::Random or String::Random