我正在构建一个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:安全处理失败错误 这告诉我,我的证书,防火墙和路由已经完成,我正在接收服务并从他们的服务中获得响应。
提前感谢你提供任何帮助。