2010-04-26 3 views
6

ich ein Passwort-Hash, die in einer Tabelle gespeichert und dort Script- durch die folgende Coldfusion setzenVergleichen Passwort-Hashes zwischen C# und Coldfusion (CFMX_COMPAT)

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

Ich versuche, einige außerhalb Funktionalität hinzugefügt, die in aC# -Anwendung. Ich möchte die bereits vorhandenen Daten nutzen können, um Benutzer authentifizieren zu können. Weiß jemand, wie ich den oben genannten Coldfusion-Code in C# replizieren kann?

Danke für irgendwelche Gedanken.

+0

Welche Verschlüsselungsalgorithmus wird verwendet? – SLaks

+0

Siehe meine Antwort unten. –

+0

Unten ist der CFMX_Compat-Code aus dem Railo-Projekt portiert nach C# – Seibar

Antwort

2

Ich lasse die ursprüngliche Antwort Inhalt unten für historische Referenz, aber es sollte beachtet werden, dass dies ist keine funktionierende Antwort auf die ursprüngliche Frage.

Stattdessen sehen Sie die am häufigsten gewählte Antwort in diesem Thread von @Terrapin im Januar 2011. Ich hoffe, das OP sieht dies und kann die akzeptierte Antwort ändern. Verdammt, ich werde sogar die Mods markieren, um zu sehen, ob etwas dagegen unternommen werden kann.


auf der Antwort von Edward Smith, und den nachfolgenden Kommentaren von czuroski zu bauen, hier meine Lösung ist.

Zuerst benötigen Sie eine XOR-Funktion in C#, die ich von here genommen und geringfügig geändert habe.

Dann nehmen Sie das Ergebnis der XOR-und Base-64 kodieren Sie es.Nachdem Sie diese Zeichenfolge haben, MD5 Hash es. Das Ergebnis sollte mit dem Ergebnis des ursprünglichen Code-Snippets übereinstimmen:

+0

Danke - Ich habe es versucht, aber es funktioniert immer noch nicht. Eigentlich ist der Schlüssel, den ich habe, tatsächlich eine Zeichenkette - kein int, also weiß ich nicht, ob das den Schlüssel ablegt, oder ob ich den Schlüssel für die Basis-64-Codierung verwenden muss. Um Base-64 zu kodieren, kann ich einfach Convert.ToBase64String verwenden oder nicht? – czuroski

+0

Gemäß der [Docs] (http://goo.gl/zGbJ) wird die übergebene Zeichenfolge als Zufalls-Seed verwendet, um den Integer-Schlüsselwert zu generieren. Leider habe ich keine weiteren Informationen darüber, wie genau dieser Wert erreicht wird. Wenn ich in Ihren Schuhen wäre, könnte ich (1) die Verschlüsselung von bestehenden Passwörtern entfernen (einfach genug mit einem einmaligen Skript), und (2) den vorhandenen CF-Code neu schreiben, um keine Verschlüsselung mehr zu verwenden. Hashing ist ausreichend, und Verschlüsselung verschwendet in diesem Fall meiner Meinung nach CPU. –

+0

yeah - Ich stimme zu, dass es CPU verschwendet, aber dies ist eine unterstützte Anwendung und ich kann das jetzt nicht ändern. Also muss ich versuchen, es selbst zu entschlüsseln, aber habe kein Glück gehabt. – czuroski

3

MD5 ist der Standard-Hashing-Algorithmus für die hash(). Ich bin kein C# -Programmierer, aber es sollte nicht zu schwer sein, einen MD5-Hash zu erstellen, um ihn mit Ihrem ColdFusion-Ergebnis zu vergleichen.

Wie für encrypt(), gibt es einen Grund, dass Sie den Benutzernamen vor dem Hashing verschlüsseln? Ich kann mir keinen Nutzen daraus machen, aber das bedeutet nicht, dass es keinen gibt. Ich würde einfach tun:

Hash(UCase(GetPass.username)) 

Welche sollte in C# einfacher zu replizieren sein.

+0

Ich stimme zu, die Verschlüsselung ist bestenfalls trivial. –

+1

Aber seine Daten enthalten es bereits, also sucht er nach einer Antwort, wo er bereits "verschlüsselte" Daten verwenden kann. –

+0

Ja - die Daten sind schon da, also versuche ich es nur zu benutzen. – czuroski

1

Eine der Lösungen wäre die DB zu tun haben, das Hashing und encription könnte einfacher sein ...

+0

ja - das wäre einfacher. Leider habe ich die Erstanwendung nicht geschrieben und möchte sie nicht ändern. – czuroski

1

Der Standard "Verschlüsselung" in CF ist einfach ein XOR:

Chiffretext = base64_encode (Klartext^Schlüssel)

so, zu entschlüsseln:

Klartext = base64_decode (Chiffretext)^Schlüssel

Der Standard-Hash, wie menti oned, ist md5.

Edit:

Nun, weitere Forschung zeigt dies nicht wahr ist - nur eine von diesen allgegenwärtigen Mythen.

Ich kann keine Dokumentation des tatsächlichen Algorithmus für die Verschlüsselungsmethode CFMX_COMPAT finden.

Sorry wegen der wilden Gans Chase.

+0

Ich schätze, alles läuft auf den Wert der Variablen "EnCode" hinaus. – mwcz

+0

Richtig, das ist nur der Schlüssel. Ich bin sicher, dass das OP in seinem CF-Quellcode darauf zugreifen kann. –

+0

Ich kann nicht scheinen, dass dies zusammenpasst. Ich habe versucht, es auf einer Test-CF-Seite einzugrenzen, um nur die Verschlüsselung durchzuführen (und den Hash zu ignorieren), aber ich kann den verschlüsselten CF-Wert immer noch nicht mit meinem verschlüsselten C# -Wert vergleichen. Ich benutzte eine direkte Base64-Verschlüsselung in meiner C# -App. Ich habe irgendwo gesehen, dass CF im Rahmen der Verschlüsselung auch einen Uuencode durchführt - gibt es da eine Wahrheit? – czuroski

10

Ich sah durch den Railo-Code als jemand anderes hier in Kommentaren erwähnt.

Im Folgenden wird CFMX_Compat aus der Railo-Java-Quelle nach C# portiert. Siehe unten für ein Anwendungsbeispiel.

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); 
     } 
    } 
} 

Hier ist ein Anwendungsbeispiel, dass die verschlüsselten Text Hex-codiert und entschlüsselt dann die gleiche Sache.

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); 
+1

Dieser C# -Port des Railo-Codes ist der eigentliche Arbeitsalgorithmus, der CFs Verschlüsseln/Entschlüsseln mit CFMX_COMPAT zuordnet. Andere XOR-basierte Algorithmen (die in ihrem eigenen Kontext korrekt sind) sind mit ColdFusion Encrypt/Decrypt nicht kompatibel. Dies ist die Version, die Sie verwenden möchten. –

Verwandte Themen