2011-07-31 4 views
3

SQL Server 2008には、既存のPHP Webアプリケーションのストアドプロシージャを使用してユーザー認証を実行する既存のデータベースがあります。 Webアプリケーションはストアドプロシージャに文字列を送信しますが、ストアドプロシージャはSQLチェックサム(http://msdn.microsoft.com/en-us/library/ms189788.aspx)で値をチェックし、ストアします。ストアドプロシージャは、文字列をNVARCHAR(50)としてキャストし、CHECKSUMをintとしてuserテーブルに格納します。JavaでSQL CHECKSUMを実装する

私は今、既存のデータベースの上に新しいJavaアプリケーションを書いています、と私は、カスタムスプリング認証マネージャを書いています。 JavaでCHECKSUMアルゴリズムを再実装したいので、変換を実行するためにストアドプロシージャを呼び出す必要はありませんが、SQL CHECKSUMの動作に関するドキュメントは見つかりません。

しかし私はそれがSQL CHECKSUMと同じ値を返すことに失敗し、それがCRC32だったことを推測して、次のコードを試してみました:

String pass = "foobar"; 
CRC32 crc32 = new CRC32(); 
crc32.update(pass.getBytes("UTF-16")); //This is due to the stored procedure casting as nvarchar 
crc32.getValue(); 

誰もがSQLチェックサムが私を使用するアルゴリズムに私を指すことができますそれをJavaで再実装できますか?

問題は、どのアルゴリズムがセキュリティのために最良のハッシュを提供するかではありません。セキュリティは、システム全体のパスワードを強制的にリセットする準備ができていないため、この特定のインスタンスの要件の範囲外です。問題は、T-SQL CHECKSUMがどのアルゴリズムを使用しているかであり、その結果、再実装できるということです。この特定のユースケースはauthですが、多くの異なるアプリケーションではこれが必要である可能性があります。

+0

は、あなただけのいくつかの既存のJava機能を使用して、新しいハッシュですべてのデータを更新することができませんか?おそらく、現在のものを保持するための新しい列として(おそらく)。これはあまりにも役立つかもしれませんhttp://stackoverflow.com/q/331157/27535 – gbn

+2

それは最終的なオプションになる必要が終了する可能性があります。ただし、元のパスワードはデータベースに保存されていないため、既存のアカウントのパスワードをリセットする必要があります。 – aweigold

+2

@aweigold:正しい方法でパスワードを扱うための+1: –

答えて

-1

私はあなたが簡単にJavaで実装MD5を見つけるように、あなたはMD5アルゴリズムでHASBYTESTSQL CHECKSUMを交換することをお勧め。あなたがHASHBYTESから取得します

もう一つの利点は、より安定した動作です。 CHECKSUMは、異なる入力に対して同じハッシュを生成する可能性があります。

はMD5でHASHBYTESを使用する方法を参照してください:

HASHBYTES('MD5', @input) 

EDIT:あなたはMD5を使用しない場合はMD5

HASHBYTESに関するコメントへの回答もSHASHA1アルゴリズムので、何の問題の両方をサポート

+0

私はこれに絶対に同意します。しかし、私は既存のユーザーアカウントを維持したいので、このオプションはユーザーにパスワードを再設定する必要があります。 – aweigold

+0

Deal lord、no。認証にmd5を使用しないでください。 –

+1

これにはまだストアドプロシージャまたはSQL呼び出しが必要です.OPはこれを削除します。 – gbn

1

SQL Serverフォーラムでは、このpageには、

と記載されています。

SQL Serverの組み込みCHECKUM関数は、一連の4ビット左回転xor演算で構築されています。詳細はpostを参照してください。

は、私はC#に移植BINARY_CHECKSUMすることができた(すみません、私は手元にJavaコンパイラを持っていない)、それが動作しているようだ...私は後で平野CHECKSUMで見ることになります...

private int SQLBinaryChecksum(string text) 
{ 
    long sum = 0; 
    byte overflow; 
    for (int i = 0; i < text.Length; i++) 
    { 
     sum = (long)((16 * sum)^Convert.ToUInt32(text[i])); 
     overflow = (byte)(sum/4294967296); 
     sum = sum - overflow * 4294967296; 
     sum = sum^overflow; 
    } 

    if (sum > 2147483647) 
     sum = sum - 4294967296; 
    else if (sum >= 32768 && sum <= 65535) 
     sum = sum - 65536; 
    else if (sum >= 128 && sum <= 255) 
     sum = sum - 256; 

    return (int)sum; 
} 
+0

これは有望そうです。私は時間があるときそれをチェックし、それが働くなら答えを受け入れる。 – aweigold

+1

申し訳ありませんが、忙しいですが、私はこれを試しました。そして、BINARY_CHECKSUMのために働きます。後でCHECKSUMで何かを見つけることができるかどうかがわかります。あなたが興味を持っているなら、私はここですばらしい要点を持っています。https://gist.github.com/aweigold/7144091#file-binarychecksum-groovy – aweigold