 |
|
|
 |
|
 |
Hi Jeroen-bart Engelen,
Thanks for providing Unix crypt algorithm, its best suits my application requirement.
My concern is, can i use this code in our Client Project?
Please revert back as soon as possible !!
Thanks & Regards,
Sravan Kumar V
|
|
|
|
 |
|
|
 |
|
 |
Are you saying passwords in unix are 8 chars long and all characters after the 8th are irrelevant? That would be news to me, so I'm curious if I'm interpreting your comment right. Perhaps you could fill in the gap by citing the code you use to generate and encrypted unix password in the form:
encrypted_password_to_write_to_passwd_file = my_encrypter(my_plain_text_password_as_I_typed_it)
It's clearly not:
encrypted_password_to_write_to_passwd_file = crypt(my_plain_text_password_as_I_typed_it)
What is the missing code in my_encrypter?
Forgive me if it's obvious or easily found elsewhere.
Cheers.
|
|
|
|
 |
|
 |
Worked great!!! Thank you for posting this article.
|
|
|
|
 |
|
 |
I get an IndexOutOfRangeException at the following code block:
uint firstSaltTranslator = m_saltTranslation[Convert.ToUInt32(firstSaltCharacter)];
because the firstSaltCharacter is greater than 127. I'm working with shift-jis encoded strings and don't know what to do about it.
|
|
|
|
 |
|
 |
So, the linux implementation is actually different that reported in the man pages. You need to modify the salt lookup to wrap values outside of the valid range of characters (ascii values 46-122) so that they fall in that valid range. In other words, a # (pound) symbol is ascii 35. 35 is 11 less than 46, so we need to use the numerical equivalent of "p" instead (p = 112) because we are wrapping back from 123 - (46 - 35). The opposite direction of wrapping would be needed for "}", which is ascii 125 (resulting in 48, which is the equivalent of the number 0). So, you fix this on the following lines in "public static string Crypt(string encryptionSalt, string textToEncrypt)": // Old version uint firstSaltTranslator = m_saltTranslation[Convert.ToUInt32(firstSaltCharacter)]; uint secondSaltTranslator = m_saltTranslation[Convert.ToUInt32(secondSaltCharacter)] << 4; // New version uint firstSaltTranslator = saltTranslationLooped(firstSaltCharacter); uint secondSaltTranslator = saltTranslationLooped(secondSaltCharacter) << 4; // And then you need to add this function private static uint saltTranslationLooped(char lookupChar) { uint lookupValue = Convert.ToUInt32(lookupChar); while (lookupValue < 46) { // Minimum valid character in a salt lookupValue += 77; // Loop into the valid range: 46-122 (77 valid characters) } while (lookupValue > 122) { // Maximum valid character in a salt lookupValue -= 77; // Loop into the valid range: 46-122 (77 valid characters) } return m_saltTranslation[lookupValue]; }
|
|
|
|
 |
|
 |
Hi
Does anyone know how to implement md5 functionality into this code?
|
|
|
|
 |
|
 |
Hello
The class works great except in the case of using for example "$$" as salt, in that case if the word is "aa", the results are:
Unix crypt() => $$vgnAFDOWbUY
C# crypt() => $$fSB9dos.RVM
The only case when the results are diferent that i found is in the case of using the "#" caracter.
Can anyone help me?
|
|
|
|
 |
|
 |
Hello st2015,
Take a look at unix "man 3 crypt". Like you can see:
--<cut>--------------------------------------------------------------------------------
char *crypt(const char *key, const char *salt);
DESCRIPTION
crypt() is the password encryption function. bla,bla,bla...:
key is a user’s typed password.
salt is a two-character string chosen from the set [a–zA–Z0–9./]. This string is used to perturb the algorithm in one of 4096 different ways.
--<cut>--------------------------------------------------------------------------------
So, you can not use "$$" as salt.
{}s Miguel
Mrcl
|
|
|
|
 |
|
 |
So, the linux implementation is actually different that reported in the man pages. You need to modify the salt lookup to wrap values outside of the valid range of characters (ascii values 46-122) so that they fall in that valid range. In other words, a # (pound) symbol is ascii 35. 35 is 11 less than 46, so we need to use the numerical equivalent of "p" instead (p = 112) because we are wrapping back from 123 - (46 - 35). The opposite direction of wrapping would be needed for "}", which is ascii 125 (resulting in 48, which is the equivalent of the number 0). So, you fix this on the following lines in "public static string Crypt(string encryptionSalt, string textToEncrypt)": // Old version uint firstSaltTranslator = m_saltTranslation[Convert.ToUInt32(firstSaltCharacter)]; uint secondSaltTranslator = m_saltTranslation[Convert.ToUInt32(secondSaltCharacter)] << 4; // New version uint firstSaltTranslator = saltTranslationLooped(firstSaltCharacter); uint secondSaltTranslator = saltTranslationLooped(secondSaltCharacter) << 4; // And then you need to add this function private static uint saltTranslationLooped(char lookupChar) { uint lookupValue = Convert.ToUInt32(lookupChar); while (lookupValue < 46) { // Minimum valid character in a salt lookupValue += 77; // Loop into the valid range: 46-122 (77 valid characters) } while (lookupValue > 122) { // Maximum valid character in a salt lookupValue -= 77; // Loop into the valid range: 46-122 (77 valid characters) } return m_saltTranslation[lookupValue]; }
|
|
|
|
 |
|
 |
I thought I was doomed WinDbg ASPCrypt and write this code myself. Your super duper!!!!!!!!!!
|
|
|
|
 |
|
 |
Thankyou, this class works awesome for making logins in a htpasswd file. I'm such an idiot, I spent an hour searching for an answer on google, when the answer was right here all along at the code project.
|
|
|
|
 |
|
 |
Hi,
I read about the crypt implementation in C# and it work perfect except when as a salt I'm using special characters. In my database there are passwords like this "[|cmrZSiAAOZ." without the "". The pass is "darkocobe" without "". My salt is the first two characters in the encrypted pass. So if i try to write darkocobe my pass and compare with this [|cmrZSiAAOZ. it is false because the class programed probably has a problem if I'm using special characters for salt.
I'm using the class UnixCrypt in C# that i found on this site.
Can anyone help me?
|
|
|
|
 |
|
 |
Ok, so this post is like 4 years old, but I found the solution. You need to modify the salt lookup to wrap values outside of the valid range of characters (ascii values 46-122) so that they fall in that valid range. In other words, a # (pound) symbol is ascii 35. 35 is 11 less than 46, so we need to use the numerical equivalent of "p" instead (p = 112) because we are wrapping back from 123 - (46 - 35). The opposite direction of wrapping would be needed for "}", which is ascii 125 (resulting in 48, which is the equivalent of the number 0). So, you fix this on the following lines in "public static string Crypt(string encryptionSalt, string textToEncrypt)": // Old version uint firstSaltTranslator = m_saltTranslation[Convert.ToUInt32(firstSaltCharacter)]; uint secondSaltTranslator = m_saltTranslation[Convert.ToUInt32(secondSaltCharacter)] << 4; // New version uint firstSaltTranslator = saltTranslationLooped(firstSaltCharacter); uint secondSaltTranslator = saltTranslationLooped(secondSaltCharacter) << 4; // And then you need to add this function private static uint saltTranslationLooped(char lookupChar) { uint lookupValue = Convert.ToUInt32(lookupChar); while (lookupValue < 46) { // Minimum valid character in a salt lookupValue += 77; // Loop into the valid range: 46-122 (77 valid characters) } while (lookupValue > 122) { // Maximum valid character in a salt lookupValue -= 77; // Loop into the valid range: 46-122 (77 valid characters) } return m_saltTranslation[lookupValue]; }
|
|
|
|
 |
|
 |
Can I use this source code in our project straight away? Or do I need to get some licensing for this?
|
|
|
|
 |
|
 |
It's a C# port of a Java implementation that I found here: http://www.dynamic.net.au/christos/crypt/, it seems that version is based on a version of an unknown author, but it might have been from the project mentioned on the page.
IANAL, so I don't know how the licensing works in this scenario. The code I posted is free to be (ab)used however you see fit, unless ofcourse some license is inherited by the code that is was based on.
Worst-case scenario, you reimplement the code you see here, because it's based on an algorithm that's GPLed for sure (it's in Linux), so it should only have a copyright thing going for as far as I know. But again, IANAL, check with one to be sure.
|
|
|
|
 |
|
 |
Actually, come to think of it, even the copyright is not a problem. I used the Java source to help me explain the algorithm and I reimplemented it in C#. So unless the algorithm requires a license I think it's safe (be sure to check with a lawyer though, these laws are tricky).
If it's indeed just copyright that could affect the source I posted here then I'm giving it away for free. Anyone can use it how they see fit.
|
|
|
|
 |
|
 |
Thank you so much for this article. IT has helped me a lot.
-RT
|
|
|
|
 |
|
 |
Hi,
First of all, thank you very much for sharing your implementation with the world.
The algorithm UNIX's crypt uses depends on the salt provided.
If its of 2 characters, it uses DES algorithm.
If it starts with $1$salt, it uses MD5.
The code you've presented seems only to support DES algorithm.
I'm wondering if there is one that also supports MD5 algorithm.
srivalli
|
|
|
|
 |
|
 |
To be honest, I didn't even know what encryption was used. I read that different flavours of Unix have their own encryption scheme. I just ported the code and created a small Unix app to encrypt strings. Then I created a set of around 100,000 different strings and had the program encrypt it, then I would test the output with my C# version. They seemed the same.
For our needs it was sufficient, we didn't use the "$1$salt" functionality you mentioned. But if you want to MD5 sum a string, why not use the MD5 class from System.Security.Cryptography? Or does the crypt() function do domething more then just compute the MD5 hash?
If not, just edit the 'public static string Crypt(string encryptionSalt, string textToEncrypt)' function and do a check on the encryptionSalt param. If it's set to "$1$salt", use the MD5 class, if not, use the code as it was.
|
|
|
|
 |
|
|
 |
|
 |
This was exactly what the Dr. ordered... except I'm not a Dr., and technically I didn't order it. However, I'll definitely be putting this one to use.
"...practice safe hex when IM'ing"
--Shawn L. Morrissey, Managing Editor, MSDN Online ( MSDN Flash; Volume 8, Number 20, 10/4/2004)
|
|
|
|
 |
|
 |
Glad you like it
|
|
|
|
 |
|
 |
What is that "MPF (Microsoft Provisioning Framework)"? Never heard of.
--
Affordable Windows-based CMS: www.zeta-producer.com
|
|
|
|
 |