Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Der SHA1-Hash der Mitgliedschaft ist nicht für alle Benutzer gleich

Hm .. Ich denke, etwas kann schief gehen, wenn die beiden Werte verkettet werden. Das Hashing sollte wirklich ein Byte-Array verwenden, wie bei der Verschlüsselungsversion , aber leider der Hash() von CF9 Funktion unterstützt es nicht - nur Zeichenfolgen. (Obwohl schlecht dokumentiert, wird es in CF11 unterstützt). Ich bin mir nicht sicher, ob es einen reinen CF-Workaround für CF9 gibt. In der Zwischenzeit könnten Sie Java jedoch direkt verwenden:

<cfscript>
    thePassword = "[email protected]";
    base64Salt = "+muo6gAmjvvyy5doTdjyaA==";

    // extract bytes of the salt and password
    saltBytes = binaryDecode(base64Salt, "base64");
    passBytes = charsetDecode(thePassword, "UTF-16LE" );

    // next combine the bytes. note, the returned arrays are immutable, 
    // so we cannot use the standard CF tricks to merge them    
    ArrayUtils = createObject("java", "org.apache.commons.lang.ArrayUtils");
    dataBytes = ArrayUtils.addAll( saltBytes, passBytes );

    // hash binary using java
    MessageDigest = createObject("java", "java.security.MessageDigest").getInstance("SHA-1");
    MessageDigest.update(dataBytes);    
    theBase64Hash = binaryEncode(MessageDigest.digest(), "base64");

    WriteOutput("<br />theBase64Hash= "& theBase64Hash &"<br/>");
    WriteOutput("DBPassword= nfcqQBgeAm0Dp1oGZI0O70Y6DvA= <br />");
</cfscript>

Aktualisierung:

Nachdem ich mich weiter umgesehen habe, glaube ich nicht, dass es eine reine CF-Lösung gibt. Die UTF-16LE-Kodierung ist nur ein Teil des Problems. Das andere Problem ist, dass DNN jeden String separat dekodiert , die andere Bytes erzeugen kann, als wenn beide als einzelnes dekodiert werden Zeichenfolge (siehe Vergleich unten). Im Fall Ihres zweiten Passworts ist dies der Fall, weshalb der endgültige Hash anders ist. Seit hash akzeptiert keine Byte-Arrays, ich glaube nicht, dass es das richtige Werkzeug für diesen Job ist. MessageDigest ist der richtige Weg.

Byte-Array-Vergleich

           old|   new | 
   1 |     -6 |    -6 | 
   2 |    107 |   107 | 
   3 |    -88 |   -88 | 
   4 |    -22 |   -22 | 
   5 |      0 |     0 | 
   6 |     38 |    38 | 
   7 |   -114 |  -114 | 
   8 |     -5 |    -5 | 
   9 |    -14 |   -14 | 
  10 |    -53 |   -53 | 
  11 |   -105 |  -105 | 
  12 |    104 |   104 | 
  13 |     -3 |    77 | **
  14 |     -1 |   -40 | **
  15 |     68 |   -14 | **
  16 |      0 |   104 | **
  17 |     84 |    68 | **
  18 |      0 |     0 | 
  19 |     33 |    84 | **
  20 |      0 |     0 | 
  21 |     64 |    33 | **
  22 |      0 |     0 | 
  23 |     49 |    64 | **
  24 |      0 |     0 | 
  25 |     50 |    49 | **
  26 |      0 |     0 | 
  27 |        |    50 | **
  28 |        |     0 | **
  • alt => charsetDecode( theSalt &thePassword, "UTF-16LE")
  • neu => ArrayUtils.addAll( saltBytes, passBytes );