2

私たちのパートナーは、token というパラメーターを含む Web サービスを呼び出しています。トークンは 2 つの数値の MD5 ハッシュの結果であり、パートナー システムを使用してユーザーを認証するのに役立ちます。当社のパートナーは、ユーザーに 2 つの文字列を要求し、それらを連結して MD5 を介して実行し、Web サービスを呼び出します。MD5 の結果はトークンであり、文字列として送信されます。

有効なトークンを DB に格納します。SQL Server を使用してトークンを計算するため、SQL はトークンを varbinary として格納するのが最も適しているようです。これは、MD5 計算のネイティブな結果です。

同じことをしようとする 2 つのコードがあります。送信されたトークンに基づいて値を引き出す選択クエリを実行します。1つは動的クエリを使用しますが(これは問題です)、機能します。もう 1 つは、パラメーター化された (より安全な) 方法で同じことを実行しようとしますが、機能しません - トークンを見つけることができません。

これが2つの競合する試みです。まず、失敗するパラメータ化されたバージョン:

byteArrayToken = System.Text.UnicodeEncoding.Unicode.GetBytes(stringToken)
scSelectThing.CommandText = "select thing from tokenstable where token=@token"
Dim param As SqlParameter = scSelectThing.Parameters.Add("@token", SqlDbType.VarBinary)
param.Value = byteArrayToken
lbOutput2.Text = scSelectThing.ExecuteScalar()

次に、動作する動的クエリ文字列バージョン:

Dim scSelectThing As New SqlCommand
 scSelectThing.CommandText = "select thing from tokenstable where token=convert(varbinary, " + stringToken + " )"
lbOutput2.Text = scSelectThing.ExecuteScalar()

SQL プロファイラーを実行すると、DB に対して実際に実行されるのは次のとおりです。

exec sp_executesql N'select thing from tokenstable where token=@token',N'@token varbinary(68)',@token=0x3000780046003800380034004100450036003400430038003300440033004100380034003800460046004300380038004200390034003400330043004200370042004600

これは私には正しく見えません。スタック内の何かがどこかで間違った変換を行うように導く何かをしているように見えます。

それが何であるかについてのアイデアはありますか?そこに動的クエリを使用して起動することは明らかに受け入れられません。

編集:

文字列は MD5 ハッシュ結果です。Query Analyzer で機能させるには、次のようにします。

select * from tokenstable where 
token=convert(varbinary, 0xF664AE32C83D3A848FFC88B9443CB7BF )

引用符がないことに注意してください。引用すると、クエリは失敗します。比較対象のフィールドは varbinary で、SQL Server が MD5 計算の結果を格納しています。

4

1 に答える 1

2

あなたの問題は、文字列からバイナリへの変換で異なるエンコーディングが使用されている可能性があります。System.Text.Encoding.ASCIIの代わりに使用してみてUnicode、それがうまくいくかどうかを確認してください。私の推測では、文字列をではなく であるconvert()と考えており、独自の文字列からバイナリへの変換に Unicode ではなく ASCII を使用しています。varcharnvarchar

編集

また、この文字列はハッシュに相当する実際のバイナリですか、それとも 16 進数表現ですか?

編集 2

次に、問題は、バイナリ データの 16 進数表現のバイナリ表現を渡していることです。それは十分に混乱しますか?

パラメータの値として追加する前に、16進数stringを配列に変換するだけです。この質問byteへの回答から取られた(そして VB.NET に翻訳された) 次のコードでそれを行うことができます:

Public Shared Function StringToByteArray(ByVal hex As String) As Byte()
    Dim NumberChars As Integer = hex.Length

    Dim bytes(NumberChars / 2) As Byte

    For i As Integer = 0 To NumberChars - 1 Step 2
        bytes(i / 2) = Convert.ToByte(hex.Substring(i, 2), 16)
    Next

    Return bytes
End Function

したがって、コードは次のようになります...

byteArrayToken = StringToByteArray(stringToken)
scSelectThing.CommandText = "select thing from tokenstable where token=@token"
Dim param As SqlParameter = scSelectThing.Parameters.Add("@token", SqlDbType.VarBinary)
param.Value = byteArrayToken
lbOutput2.Text = scSelectThing.ExecuteScalar()
于 2009-06-10T16:42:21.670 に答える