I am building a VB.Net WCF client to access an Axis web service. I have already found a lot of great help with creating the Security Header which is not described in the WSDL. This is based on the OASIS specifications and very similar to this question. However, I have found a number of C# solutions which describe generating the Nonce and Password Digest, but I can't see what I am doing wrong. I based my implementation on this article.
Here is my code for generating and validating the Nonce and 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
My nonce is defined for the class as: Private _nonce As Byte() = New Byte(15) {}
It is populated like so:
Dim rndGenerator As RandomNumberGenerator = New RNGCryptoServiceProvider()
rndGenerator.GetBytes(_nonce)
I can generate my PasswordDigest and "un-hash" it with the ValidateToken formula, but I cannot Validate a "known-good" example from the vendor by taking their PasswordDigest, and attempting to re-make it from the shared password, Created time and nonce as base 64. That indicates to me that we are using different algorithms for the Digest.
Does anyone know of a VB.Net example for this or could I get some pointers as to what I'm doing wrong? I'm thinking I must have gotten something wrong with my understanding of the formula Digest = Base64(SHA1(nonce + created + password))
My nonce is 16 bytes. Here is the redacted security header:
<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>
The specific error I get is that: WSDoAllReceiver: security processing failed error That tells me that I have my certificate, firewall and routing worked out, I'm reaching the service and getting a response from their service.
Thank you in advance for any help with this.