如何在VB.Net中为WCF服务生成带有PasswordDigest的UserName令牌

时间:2015-02-19 19:11:38

标签: wcf service soap-client

我正在构建一个VB.Net WCF客户端来访问Axis Web服务。我已经在创建WSDL中没有描述的Security Header方面找到了很多帮助。这基于OASIS specifications,与this question非常相似。但是,我发现了许多描述生成Nonce和Password Digest的C#解决方案,但我看不出我做错了什么。我的实施基于this article

以下是我生成和验证Nonce和PasswordDigest的代码:

Public Function GetPasswordDigestAsBase64() As String
    'Nonce is already generated as a cryptographically strong random value
    Dim sRetval As String = ""

    'Get other operands to the right format
    Dim time As Byte() = Encoding.UTF8.GetBytes(GetCreatedAsString())
    Dim pwd As Byte() = Encoding.UTF8.GetBytes(SystemPassword)
    Dim operand As Byte() = New Byte(_nonce.Length + time.Length + pwd.Length - 1) {}
    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
    Dim sha As SHA1 = SHA1.Create()
    sRetval = Convert.ToBase64String(sha.ComputeHash(operand))
    'If ValidateToken(sRetval, GetNonceAsBase64, GetCreatedAsString) Then
    '    Dim sDebug As String = "Yes"
    'Else
    '    Dim sFail As String = "No"
    'End If
    Return sRetval
End Function

Public Function ValidateToken(password As String, sNonceAsBase64 As String, sCreated As String) As Boolean
    'Convert Nonce
    Dim testNonce As Byte() = Convert.FromBase64String(sNonceAsBase64)
    Dim pwd As Byte() = Encoding.UTF8.GetBytes(ConfigurationManager.AppSettings("Password"))
    'Dim pwd As Byte() = Encoding.UTF8.GetBytes(password)
    Dim createdBytes As Byte() = Encoding.UTF8.GetBytes(sCreated)
    Dim operand As Byte() = New Byte(testNonce.Length + createdBytes.Length + (pwd.Length - 1)) {}
    Array.Copy(testNonce, operand, testNonce.Length)
    Array.Copy(createdBytes, 0, operand, testNonce.Length, createdBytes.Length)
    Array.Copy(pwd, 0, operand, testNonce.Length + createdBytes.Length, pwd.Length)
    Dim sha1__1 As SHA1 = SHA1.Create()
    Dim trueDigest As String = Convert.ToBase64String(sha1__1.ComputeHash(operand))

    Return [String].Compare(trueDigest, password) = 0
End Function

我的nonce被定义为类:         Private _nonce As Byte()= New Byte(15){}

它的填充方式如下:

    Dim rndGenerator As RandomNumberGenerator = New RNGCryptoServiceProvider()
    rndGenerator.GetBytes(_nonce)

我可以使用ValidateToken公式生成我的PasswordDigest和“un-hash”,但是我无法通过获取他们的PasswordDigest并尝试从共享密码重新创建它来验证供应商的“已知良好”示例,创建时间和nonce作为基数64.这向我表明我们正在使用不同的摘要算法。

有没有人知道这个VB.Net的例子,或者我可以得到一些关于我做错的指示?我在想我对公式的理解Digest = Base64(SHA1(nonce + created + password))

我的现时是16个字节。以下是编辑的安全标头:

    <wsse:Security s:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsu:Timestamp wsu:Id="TS-2"> 
<wsu:Created>2015-02-18T15:20:16.000Z</wsu:Created>
<wsu:Expires>2015-02-18T15:25:16.000Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken wsu:Id="UsernameToken-1">
<wsse:Username>MyUserName</wsse:Username>          
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">MyPassHashed</wsse:Password>          
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">5VlfBQDItoCHHx3xmWikEg==</wsse:Nonce>          
<wsu:Created>2015-02-18T15:20:16.000Z</wsu:Created>        
</wsse:UsernameToken>      
</wsse:Security>

我得到的具体错误是:WSDoAllReceiver:安全处理失败错误 这告诉我,我的证书,防火墙和路由已经完成,我正在接收服务并从他们的服务中获得响应。

提前感谢你提供任何帮助。

0 个答案:

没有答案