7

WS-Security に問題があり、正しい nonce とパスワード ダイジェストを作成しています。

SoapUI を使用して Oracle システムにデータを送信しています。したがって、SoapUI の呼び出しをインターセプトできます (プロキシを 127.0.0.1 ポート 8888 に変更して、SSL 経由であるために失敗する Fiddler を使用します)。これらの値は一度しか使用できないため、インターセプトは重要です。次に、ナンスを取得し、作成されたタイムスタンプとパスワード ダイジェストをコードに挿入します (値が持続しないため、これを行うのに 30 秒しかありません!)、成功します。

だから私はそれがただのパスワード ダイジェストであることを知っています。

私が使用する値は次のとおりです。

Nonce: UIYifr1SPoNlrmmKGSVOug==
Created Timestamp: 2009-12-03T16:14:49Z
Password: test8
Required Password Digest: yf2yatQzoaNaC8BflCMatVch/B8=

ダイジェストを作成するアルゴリズムは次のとおりです。

Password_Digest = Base64 ( SHA-1 ( nonce + created + password ) )

次のコードを使用 ( Rick Strahl の投稿から)

protected string GetSHA1String(string phrase)
{
    SHA1CryptoServiceProvider sha1Hasher = new SHA1CryptoServiceProvider();
    byte[] hashedDataBytes = sha1Hasher.ComputeHash(Encoding.UTF8.GetBytes(phrase));
    return Convert.ToBase64String(hashedDataBytes);
}

私は得る:

GetSHA1String("UIYifr1SPoNlrmmKGSVOug==" + "2009-12-03T16:14:49Z" + "test8") = "YoQKI3ERlMDGEXHlztIelsgL50M="

さまざまな SHA1 メソッドを試しましたが、すべて同じ結果が返されました (これは良いことだと思います!)。

SHA1 sha1 = SHA1.Create();
SHA1 sha1 = SHA1Managed.Create();

// Bouncy Castle:
protected string GetSHA1usingBouncyCastle(string phrase)
{
    IDigest digest = new Sha1Digest();
    byte[] resBuf = new byte[digest.GetDigestSize()];
    byte[] bytes = Encoding.UTF8.GetBytes(phrase);
    digest.BlockUpdate(bytes, 0, bytes.Length);
    digest.DoFinal(resBuf, 0);
    return Convert.ToBase64String(resBuf);
}

正しいハッシュを取得する方法についてのアイデアはありますか?

4

1 に答える 1

9

問題はノンスでした。

既に Base64 でエンコードされている nonce を使用しようとしていました。「UIYifr1SPoNlrmmKGSVOug==」という形式のノンスを使用する場合は、それをデコードする必要があります。

Convert.FromBase64String("UIYifr1SPoNlrmmKGSVOug==") これはバイト配列です。

したがって、新しいメソッドが必要です。

public string CreatePasswordDigest(byte[] nonce, string createdTime, string password)
{
    // combine three byte arrays into one
    byte[] time = Encoding.UTF8.GetBytes(createdTime);
    byte[] pwd = Encoding.UTF8.GetBytes(password);
    byte[] operand = new byte[nonce.Length + time.Length + pwd.Length];
    Array.Copy(nonce, operand, nonce.Length);
    Array.Copy(time, 0, operand, nonce.Length, time.Length);
    Array.Copy(pwd, 0, operand, nonce.Length + time.Length, pwd.Length);

    // create the hash
    var sha1Hasher = new SHA1CryptoServiceProvider();
    byte[] hashedDataBytes = sha1Hasher.ComputeHash(operand);
    return Convert.ToBase64String(hashedDataBytes);
}

CreatePasswordDigest(Convert.FromBase64String("UIYifr1SPoNlrmmKGSVOug=="), "2009-12-03T16:14:49Z", "test8")

これは、必要に応じて yf2yatQzoaNaC8BflCMatVch/B8= を返します。

XML に入力したのと同じ createdTime をダイジェストで使用することを忘れないでください。これは明白に聞こえるかもしれませんが、タイムスタンプにミリ秒を含める人もいれば、含めない人もいます。それは問題ではなく、一貫性が必要なだけです。

また、UsernameToken XML の Id フィールドは重要ではありません。変更する必要はありません。

Rick が使用するような GUID を使用したくない場合は、上記のようなナンスを作成する方法を次に示します。

private byte[] CreateNonce()
{
    var Rand = new RNGCryptoServiceProvider();
    //make random octets
    byte[] buf = new byte[0x10];
    Rand.GetBytes(buf);
    return buf;
}

私はそれが誰かを助けることを願っています - それは私に多くの欲求不満、試行錯誤、ウェブページの検索、そして一般的なヘッド/ウォールバンギングを要しました.

于 2013-10-17T21:55:11.630 に答える