Comparing password hashes between C # and ColdFusion (CFMX_COMPAT)

I have a hash password that is stored in a table and placed there by the next version of the coldfusion script -

#Hash(Encrypt(Form.UserPassword,GetSiteVars.EnCode))# 

I am trying to add some external features to a C # application. I would like to be able to use data that already exists so that I can authenticate users. Does anyone know how I can reproduce the above coldfusion code in C #?

Thanks for any thoughts.

+6
security c # coldfusion cryptography
source share
5 answers

I will leave the source text of the answer below for reference, but it should be noted that this is NOT a working answer to the original question .

Instead, see the answer to the top voice in this thread from @Terrapin in January 2011. I hope the OP sees this and can change the accepted answer. Damn, I’ll even celebrate mods to see if anything can be done about this.


To build on Edward Smith's answer and subsequent czuroski comments, here is my solution.

First you need the XOR function in C #, which I took from here and changed a bit.

 using System; using System.Collections.Generic; using System.Text; namespace SimpleXOREncryption { public static class EncryptorDecryptor { public static string EncryptDecrypt(string textToEncrypt, int key) { StringBuilder inSb = new StringBuilder(textToEncrypt); StringBuilder outSb = new StringBuilder(textToEncrypt.Length); char c; for (int i = 0; i < textToEncrypt.Length; i++) { c = inSb[i]; c = (char)(c ^ key); outSb.Append(c); } return outSb.ToString(); } } } 

Then take the result of XOR and base-64. Once you have this line, MD5 hash. The result should match the result of the source code snippet:

 #Hash(Encrypt(Form.UserPassword,GetSiteVars.EnCode))# 
+2
source share

I looked at the Railo code, as someone else mentioned in the comments.

Below is CFMX_Compat ported to C # from a Railo Java source. The following is an example of use.

 using System; using System.Collections.Generic; using System.Text; using System.Security.Cryptography; namespace RailoUtil { // SOURCE: Railo Source Code License LGPL v2 // http://wiki.getrailo.org/wiki/RailoLicense public class RailoCFMXCompat { private String m_Key; private int m_LFSR_A = 0x13579bdf; private int m_LFSR_B = 0x2468ace0; private int m_LFSR_C = unchecked((int)0xfdb97531); private int m_Mask_A = unchecked((int)0x80000062); private int m_Mask_B = 0x40000020; private int m_Mask_C = 0x10000002; private int m_Rot0_A = 0x7fffffff; private int m_Rot0_B = 0x3fffffff; private int m_Rot0_C = 0xfffffff; private int m_Rot1_A = unchecked((int)0x80000000); private int m_Rot1_B = unchecked((int)0xc0000000); private int m_Rot1_C = unchecked((int)0xf0000000); public byte[] transformString(String key, byte[] inBytes) { setKey(key); int length = inBytes.Length; byte[] outBytes = new byte[length]; for (int i = 0; i < length; i++) { outBytes[i] = transformByte(inBytes[i]); } return outBytes; } private byte transformByte(byte target) { byte crypto = 0; int b = m_LFSR_B & 1; int c = m_LFSR_C & 1; for (int i = 0; i < 8; i++) { if (0 != (m_LFSR_A & 1)) { m_LFSR_A = m_LFSR_A ^ m_Mask_A >> 1 | m_Rot1_A; if (0 != (m_LFSR_B & 1)) { m_LFSR_B = m_LFSR_B ^ m_Mask_B >> 1 | m_Rot1_B; b = 1; } else { m_LFSR_B = m_LFSR_B >> 1 & m_Rot0_B; b = 0; } } else { m_LFSR_A = (m_LFSR_A >> 1) & m_Rot0_A; if (0 != (m_LFSR_C & 1)) { m_LFSR_C = m_LFSR_C ^ m_Mask_C >> 1 | m_Rot1_C; c = 1; } else { m_LFSR_C = m_LFSR_C >> 1 & m_Rot0_C; c = 0; } } crypto = (byte)(crypto << 1 | b ^ c); } target ^= crypto; return target; } private void setKey(String key) { int i = 0; m_Key = key; if (String.IsNullOrEmpty(key)) key = "Default Seed"; char[] Seed = new char[key.Length >= 12 ? key.Length : 12]; Array.Copy(m_Key.ToCharArray(), Seed, m_Key.Length); int originalLength = m_Key.Length; for (i = 0; originalLength + i < 12; i++) Seed[originalLength + i] = Seed[i]; for (i = 0; i < 4; i++) { m_LFSR_A = (m_LFSR_A <<= 8) | Seed[i + 4]; m_LFSR_B = (m_LFSR_B <<= 8) | Seed[i + 4]; m_LFSR_C = (m_LFSR_C <<= 8) | Seed[i + 4]; } if (0 == m_LFSR_A) m_LFSR_A = 0x13579bdf; if (0 == m_LFSR_B) m_LFSR_B = 0x2468ace0; if (0 == m_LFSR_C) m_LFSR_C = unchecked((int)0xfdb97531); } } } 

Here is a usage example that hex encodes ciphertext and then decrypts the same.

 RailoCFMXCompat cfmx = new RailoCFMXCompat(); UTF8Encoding encoding = new UTF8Encoding(); //encrypt my string byte[] encrypted = cfmx.transformString("mySecretKey", encoding.GetBytes("clear text")); string encryptedHex = BitConverter.ToString(encrypted); //72-07-AA-1B-89-CB-01-96-4F-51 //decrypt my string byte[] encryptedBytes = HexToBytes("72-07-AA-1B-89-CB-01-96-4F-51"); byte[] decrypted = cfmx.transformString("mySecretKey", encryptedBytes); string cleartext = encoding.GetString(decrypted); 
+10
source share

MD5 is the default hash() algorithm for hash() . I am not a C # programmer, but it’s not too difficult to create an MD5 hash to compare with your ColdFusion result.

As for encrypt() , is there a reason why you encrypt your username before hashing it? I can not think of any benefit for this, but this does not mean that it is not. I would just do:

 Hash( UCase( GetPass.username ) ) 

What should be easier to replicate in C #.

+3
source share

One solution would be for the database to perform hashing and subscribing, it might be easier ...

+1
source share

By default, “encryption” in CF is just XOR:

ciphertext = base64_encode (plaintext ^ key)

So, to decrypt:

plaintext = base64_decode (ciphertext) ^ key

The default hash, as already mentioned, is md5.

Edit:

Well, further research shows that this is not true - only one of these common myths.

I can not find the documentation on the actual algorithm for the CFMX_COMPAT encryption method.

Sorry for the wild chase of geese.

+1
source share

All Articles