3

DNN ログインを使用して他の Web アプリからユーザーを認証する方法はありますか?

DNN を使用しているメイン サイトがあり、ユーザー ログインは asp ネット メンバーシップ テーブルに保存されます。私が読んだことから、パスワードはマシンキーを使用して暗号化されてからソルト化されます。この情報がどこにあるかはわかりますが、この方法を使用してパスワードを正しく暗号化できないようです。

DNN サイトと同じサーバーで Coldfusion Web アプリケーションを試していますが、うまくいきません。ColdFusion 暗号化関数を使用すると、簡単に実行できると思われるでしょう。

    Encrypt(passwordstring, key [, algorithm, encoding, IVorSalt, iterations])

何を試しても、一致する値が得られません。

ヘルプ、洞察、または正しい方向に私を向けていただければ幸いです。

4

3 に答える 3

3

(編集:元の回答がすべての場合に機能したわけではありません。大幅に改訂されました...)

私が読んだところによると、DNNはデフォルトで「SHA1」ハッシュを使用します。@barnyrが投稿したスレッドは、連結されたソルトとパスワードを単純にハッシュすることを示していますが、少しひねりがあります。

CF9のHash関数がバイナリ(CF11でサポートされている)を受け入れないことを考えると、ネイティブCF関数だけで結果を複製することはできないと思います。代わりに、文字列をバイナリにデコードしてから、Javaを直接使用することをお勧めします。

コード:

<cfscript>
    thePassword = "DT!@12";
    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("theBase64Hash= "& theBase64Hash &"<br/>");
</cfscript>


違いのデモ:

<cfscript>
    theEncoding = "UTF-16LE";
    thePassword = "DT!@12";
    base64Salt = "+muo6gAmjvvyy5doTdjyaA==";

    // extract the bytes SEPARATELY
    saltBytes = binaryDecode(base64Salt, "base64");
    passBytes = charsetDecode(thePassword, theEncoding );
    ArrayUtils = createObject("java", "org.apache.commons.lang.ArrayUtils");
    separateBytes = ArrayUtils.addAll( saltBytes, passBytes );

    // concatenate first, THEN extract the bytes 
    theSalt = charsetEncode( binaryDecode(base64Salt, "base64"), theEncoding );
    concatenatedBytes = charsetDecode( theSalt & thePassword, theEncoding );

    // these are the raw bytes BEFORE hashing
    WriteOutput("separateBytes= "& arrayToList(separateBytes, "|") &"<br>");        
    WriteOutput("concatenatedBytes"& arrayToList(concatenatedBytes, "|") );
</cfscript>


結果:

separateBytes     = -6|107|-88|-22|0|38|-114|-5|-14|-53|-105|104|77|-40|-14|104|68|0|84|0|33|0|64|0|49|0|50|0
concatenatedBytes = -6|107|-88|-22|0|38|-114|-5|-14|-53|-105|104|-3|-1|68|0|84|0|33|0|64|0|49|0|50|0 


于 2012-09-21T22:45:21.530 に答える
2

Most likely the password is not encrypted, it is hashed. Hashing is different from encrypting, because it is not reversible.

You would not use ColdFusion's encrypt() function for this, you would use its hash() function.

So the questions you'll need to answer to figure out how to hash the passwords in CF to be able to auth against the DNN users are:

  1. What algorithm is DNN using to hash the passwords?
  2. How is the salt being used with the password prior to hashing?
  3. Is DNN iterating over the hash X number of times to improve security?

All of those questions must be answered to determine how CF must use the hash() function in combination with the salt and user-submitted passwords.

I'll make some assumptions to provide an answer.

If we assume that noiteration is being done and that the salt is simply being appended to the password prior to using SHA1 to hash the password, then you'd be able to reproduce the hash digest like this:

<cfset hashDigest = hash(FORM.usersubmittedPassword & saltFromDB, "SHA1") />
于 2012-09-21T14:09:18.110 に答える
1

(「暗号化された」プロセスを「ハッシュ」とは別に保つために新しい応答を投稿する)

「暗号化された」キーの場合、DNN 側は、 machineKeyの設定に応じて、DES、3DES、または AES などの標準アルゴリズムを使用します。ただし、いくつかの違いがあるため、CF コードで一致させる必要があります。実際の設定がわからないので、3DES今のところデフォルトを使用していると仮定します。

暗号化するデータ

暗号化された値は、ソルトとパスワードの組み合わせです。ただし、ハッシュと同様に、DNN はUTF-16LEを使用します。残念ながら、ColdFusion のEncrypt()関数は常に UTF-8 を想定しているため、非常に異なる結果が生成されます。EncryptBinaryそのため、代わりに関数を使用する必要があります。

    // sample valus
    plainPassword = "password12345";
    base64Salt    = "x7le6CBSEvsFeqklvLbMUw==";
    hexDecryptKey = "303132333435363738393031323334353637383930313233";

    // first extract the bytes of the salt and password
    saltBytes = binaryDecode(base64Salt, "base64");
    passBytes = charsetDecode(plainPassword, "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 );


暗号化アルゴリズム

ブロック暗号では、ColdFusion はデフォルトでECB モードに設定されます。(「ColdFusion での強力な暗号化」を参照してください) 一方、.NET はデフォルトで CBC モードに設定されており、追加の IV 値が必要です。そのため、CF コードを一致するように調整する必要があります。

    // convert DNN hex key to base64 for ColdFusion
    base64Key  = binaryEncode(binaryDecode( hexDecryptKey, "hex"),  "base64");

    // create an IV and intialize it with all zeroes
    // block size:  16 => AES, 8=> DES or TripleDES 
    blockSize = 8; 
    iv = javacast("byte[]", listToArray(repeatString("0,", blocksize)));

    // encrypt using CBC mode 
    bytes = encryptBinary(dataBytes, base64Key, "DESede/CBC/PKCS5Padding", iv);

    // result: WBAnoV+7cLVI95LwVQhtysHb5/pjqVG35nP5Zdu7T/Cn94Sd8v1Vk9zpjQSFGSkv 
    WriteOutput("encrypted password="& binaryEncode( bytes, "base64" ));
于 2012-09-24T20:16:40.590 に答える