My Client has a Java webservice and I am trying to consumem it using wcf .
It uses a usernametoken with nonce, createddate.. This is the link I am using
http://weblog.west-wind.com/posts/2012/Nov/24/WCF-WSSecurity-and-WSE-Nonce-Authentication,
Following code generates nonce. This simply appends to the string.
string phrase = Guid.NewGuid().ToString();
var nonce = GetSHA1String(phrase);
protected string GetSHA1String(string phrase)
{
SHA1CryptoServiceProvider sha1Hasher = new SHA1CryptoServiceProvider();
byte[] hashedDataBytes = sha1Hasher.ComputeHash(Encoding.UTF8.GetBytes(phrase));
return Convert.ToBase64String(hashedDataBytes);
}
Error: The Nonce which is a randomly generated value has expired. Is the code generating a nonce or checksum?
Soap UI does not give me this error. It is successful.This is obvious becuase Interoperability is always an issue
SOAP Error, The nonce, which is a randomly generated value, has expired. ocurred while running action:
Thank you
Related
I am creating an open Source Project which uses the youtube pubsub api to get notifications on video uploads. I want to verify that the request does come from youtube and not from a 3rd Party by checking the HMAC SHA1 Signature as described.
So, every time 1 Run my Program, I will generate a Secret later, to debug the problem, i use "test" as my secret string.
I use the following method to check if the provided signature is valid
public static bool Check(string body, string signature)
{
using (var hmac = new HMACSHA1(Encoding.UTF8.GetBytes(Secret)))
{
var hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(body));
var hash = Encoding.UTF8.GetString(hashBytes);
Console.WriteLine("Computed Hash " + hash);
return signature.Equals(hash);
}
}
Where body is the request body and signature is a value provided in the request header.
According to https://pubsubhubbub.github.io/PubSubHubbub/pubsubhubbub-core-0.4.html#rfc.section.7
If the subscriber supplied a value for hub.secret in their subscription request, the hub MUST generate an HMAC signature of the payload and include that signature in the request headers of the content distribution request. The X-Hub-Signature header's value MUST be in the form sha1=signature where signature is a 40-byte, hexadecimal representation of a SHA1 signature [RFC3174]. The signature MUST be computed using the HMAC algorithm [RFC2104] with the request body as the data and the hub.secret as the key.
I supply my Secret as hub.secret in my subscription request.
So if I understand it correctly, the hub SHOULD use that secret to generate a HMACSHA1 of the payload -> the body.
I want to regenerate the HMAC and should get the same value, right?
It does not work. Also the computed hash value logged by console.WriteLine is something completely different, not alphabetic characters at all, so I guess it might be a problem with the encoding, but I can't figure it out. Thanks for all the help!
The documentation says "where signature is a 40-byte, hexadecimal representation" so instead of converting hashBytes to an UTF8 string you should convert it to a hexadecimal string.
public static bool Check(string body, string signature)
{
using (var hmac = new HMACSHA1(Encoding.UTF8.GetBytes(Secret)))
{
var hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(body));
var hash = Convert.ToHexString(hashBytes).ToLowerInvariant();
Console.WriteLine("Computed Hash " + hash);
return signature.Equals(hash);
}
}
Im trying to integrate using SOAP to a web service but I'm getting stucked in the authorization part, and more specifically when creating sha1 encrypted password.
Documentation for this specific authorization can be found at https://www.beautyfort.com/api/docs/AuthHeader-t1
I have been searching the net trying to find different ways to create the password but none seems to generate the same password as the example in the documentation page.
string testDateString = "2015-07-08T11:31:53+01:00";
string testNonce = "186269";
string testSecret = "Ok4IWYLBHbKn8juM1gFPvQxadieZmS2";
SHA1CryptoServiceProvider sha1Hasher = new SHA1CryptoServiceProvider();
byte[] hashedDataBytes = sha1Hasher.ComputeHash(Encoding.UTF8.GetBytes(testNonce + testDateString + testSecret));
string Sha1Password = Convert.ToBase64String(hashedDataBytes);
The input variables is from documentation page. According to the documentation the password should get the value "ZDg3MTZiZTgwYTMwYWY4Nzc4OGFjMmZhYjA5YzM3MTdlYmQ1M2ZkMw=="
but the code I am using is generating "2HFr6Aowr4d4isL6sJw3F+vVP9M=".
Anyone have a bright idea of what I am doing wrong?
I took a wild guess that maybe the output of "sha1()" in the documention psuedo-code was a hex-string (like sha1() in PHP, etc), and that seems to output the expected password.
Updated code:
string testDateString = "2015-07-08T11:31:53+01:00";
string testNonce = "186269";
string testSecret = "Ok4IWYLBHbKn8juM1gFPvQxadieZmS2";
SHA1CryptoServiceProvider sha1Hasher = new SHA1CryptoServiceProvider();
byte[] hashedDataBytes = sha1Hasher.ComputeHash(Encoding.UTF8.GetBytes(testNonce + testDateString + testSecret));
var hexString = BitConverter.ToString(hashedDataBytes).Replace("-", string.Empty).ToLower();
string Sha1Password = Convert.ToBase64String(Encoding.UTF8.GetBytes(hexString));
I am building login workflow using Google for user. Once user is authenticated, I call GetAuthResponse to get idToken.
https://developers.google.com/identity/sign-in/web/backend-auth
Now, I need to verify certificate against Google certificate. I am using JwtSecurityToken(C#) for the same.
I am referencing for verification - http://blogs.msdn.com/b/alejacma/archive/2008/06/25/how-to-sign-and-verify-the-signature-with-net-and-a-certificate-c.aspx
Issue is - I always gets false from VerifyHash. As, VerifyHash returns just false without any reason, I am not able to find way to verify whether idToken is
valid or not. My code is given below
String strID = ""; // idToken received from Google AuthResponse
JwtSecurityToken token = new JwtSecurityToken(strID);
byte[] text = GetHash(token.RawData);
SHA256Cng sha1 = new SHA256Cng();
UnicodeEncoding encoding = new UnicodeEncoding();
byte[] data = encoding.GetBytes(text);
byte[] hash = sha1.ComputeHash(data);
byte[] signature = Encoding.Unicode.GetBytes(token.RawSignature);
// Modulus and exponent value from https://www.googleapis.com/oauth2/v2/certs - second set of keys
String modulus = "uHzGq7cMlx21nydbz9VsW1PItetb9mqvnpLp_8E3Knyk-mjv9DlaPhKGHYlJfHYGzKa2190C5vfsLLb1MIeGfdAv7ftpFsanIWawl8Zo0g-l0m7T2yG_7XerqcVK91lFifeJtgxKI86cPdZkgRy6DaYxMuAwAlhvpi3_UhPvsIwi7M6mxE8nUNpUWodh_YjJNu3wOxKDwbBZuRV2itjY6Z7RjFgJt1CsKF-QjqSVvWjAl0LaCaeMS_8yae0ln5YNeS8rAb6xkmcOuYeyhYsiBzwLRvgpXzEVLjLr631Z99oUHTpP9vWJDpGhfkrClkbmdtZ-ZCwX-eFW6ndd54BJEQ==";
String exponent = "AQAB";
modulus = modulus.Replace('-', '+').Replace('_', '/'); // Else it gives Base64 error
StringBuilder sb = new StringBuilder();
sb.Append("<RSAKeyValue>");
sb.Append("<Modulus>");
sb.Append(modulus);
sb.Append("</Modulus>");
sb.Append("<Exponent>");
sb.Append(exponent);
sb.Append("</Exponent>");
sb.Append("</RSAKeyValue>");
RSACryptoServiceProvider RSAVerifier = new RSACryptoServiceProvider();
RSAVerifier.FromXmlString(sb.ToString());
// Verify the signature with the hash
return RSAVerifier.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA256"), signature);
You might want to try as done in the Google+ Token Verification project - this fork includes a few minor updates that are still in review.
An alternative approach is to just verify the tokens using Google's token verification endpoints:
curl https://www.googleapis.com/oauth2/v2/tokeninfo?id_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjkyNGE0NjA2NDgxM2I5YTA5ZmFjZGJiNzYwZGI5OTMwMWU0ZjBkZjAifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwic3ViIjoiMTEwNTcwOTc3MjI2ODMwNTc3MjMwIiwiYXpwIjoiMzY0MzgxNDQxMzEwLXRuOGw2ZnY2OWdnOGY3a3VjanJhYTFyZWpmaXRxbGpuLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiYXRfaGFzaCI6IlAzLU1HZTdocWZhUkZ5Si1qcWRidHciLCJhdWQiOiIzNjQzODE0NDEzMTAtdG44bDZmdjY5Z2c4ZjdrdWNqcmFhMXJlamZpdHFsam4uYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJjX2hhc2giOiJjd3hsdXBUSkc4N2FnbU1pb0tSYUV3IiwiaWF0IjoxNDM0NDcyODc2LCJleHAiOjE0MzQ0NzY0NzZ9.Gz_WljZOV9NphDdClakLstutEKk65PNpEof7mxM2j-AOfVwh-SS0L5uxIaknFOk4-nDGmip42vrPYgNvbQWKZY63XuCs94YQgVVmTNCTJnao1IavtrhYvpDqGuGKdEB3Wemg5sS81pEthdvHwyxfwLPYukIhT8-u4ESfbFacsRtR77QRIOk-iLJAVYWTROJ05Gpa-EkTunEBVmZyYetbMfSoYkbwFKxYOlHLY-ENz_XfHTGhYhb-GyGrrw0r4FyHb81IWJ6Jf-7w6y3RiUJik7kYRkvnFouXUFSm8GBwxsioi9AAkavUWUk27s15Kcv-_hkPXzVrW5SvR1zoTI_IMw
I'm currently struggling with the a JWT I'm receiving from google+ log in service. I'm trying to make several authentication services compatible with my solution, but the JWT I'm getting from google doesn't seem to work the same way as the one I retrieve from Auth0.
Made a test to simulate the behavior:
public void TestMethod1()
{
var handler = new JwtTokensConfig.MyJwtSecurityTokenHandler();
const string encodedToken = <JWT>;
const string issuer = "accounts.google.com";
IIssuerSecurityTokenProvider provider = new SymmetricKeyIssuerSecurityTokenProvider(issuer,
new FederationConfig.SymetricKey {Base64Url = <SECRET>}.Bytes);
var securityToken = provider.SecurityTokens.First();
var validationParameters = new TokenValidationParameters()
{
ValidIssuer = issuer,
AllowedAudience = "<CLIENTID>,
SigningToken = securityToken
};
handler.ValidateToken(encodedToken, validationParameters);
}
Removed the sensitive data and replaced it with <>.
When I'm running this test, I receive the following error:
Test method UnitTestProject1.UnitTest1.TestMethod1 threw exception:
System.IdentityModel.Tokens.SecurityTokenValidationException: Jwt10316: Signature validation failed. Keys tried: 'System.IdentityModel.Tokens.InMemorySymmetricSecurityKey'.
Exceptions caught:
'System.InvalidOperationException: Jwt10532: SymmetricSecurityKey.GetKeyedHashAlgorithm( 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' ) threw and exception.
SymmetricSecurityKey: 'System.IdentityModel.Tokens.InMemorySymmetricSecurityKey'
SignatureAlgorithm: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256', check to make sure the SignatureAlgorithm is supported.
Exception: 'System.InvalidOperationException: Crypto algorithm 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' not supported in this context.
at System.IdentityModel.CryptoHelper.CreateKeyedHashAlgorithm(Byte[] key, String algorithm)
at System.IdentityModel.Tokens.InMemorySymmetricSecurityKey.GetKeyedHashAlgorithm(String algorithm)
at System.IdentityModel.Tokens.SymmetricSignatureProvider..ctor(SymmetricSecurityKey key, String algorithm)'. ---> System.InvalidOperationException: Crypto algorithm 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' not supported in this context.
at System.IdentityModel.CryptoHelper.CreateKeyedHashAlgorithm(Byte[] key, String algorithm)
at System.IdentityModel.Tokens.InMemorySymmetricSecurityKey.GetKeyedHashAlgorithm(String algorithm)
at System.IdentityModel.Tokens.SymmetricSignatureProvider..ctor(SymmetricSecurityKey key, String algorithm)
--- End of inner exception stack trace ---
at System.IdentityModel.Tokens.SymmetricSignatureProvider..ctor(SymmetricSecurityKey key, String algorithm)
at System.IdentityModel.Tokens.SignatureProviderFactory.CreateProvider(SecurityKey key, String algorithm, Boolean willCreateSignatures)
at System.IdentityModel.Tokens.SignatureProviderFactory.CreateForVerifying(SecurityKey key, String algorithm)
at System.IdentityModel.Tokens.JwtSecurityTokenHandler.ValidateSignature(SecurityKey key, String algorithm, Byte[] encodedBytes, Byte[] signature)
at System.IdentityModel.Tokens.JwtSecurityTokenHandler.ValidateSignature(JwtSecurityToken jwt, Byte[] encodedBytes, Byte[] signatureBytes, IEnumerable`1 signingTokens)
I'm suspecting that this might be related to the fact that the Google JWT returns with the decoding algorithm of "alg": "RS256", but I can't say for sure. The one I get from Auth0 works just fine.
The way I'm getting the token is by using the google+ sign in method (https://developers.google.com/+/web/signin/javascript-flow) then passing the JWT to a different callback site. This page has been added to my REDIRECT URIS on the google project.
If you see anything that is missing, let me know! Any feedback is greatly appreciated.
I'm trying to create a client for the new tent.io protocol that's being developed and they are using the HTTP MAC Oauth2 scheme described by https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-http-mac-01.
I've written a simple method in C# that creates the Authorization header, but when I submit my request I get a simple "Invalid MAC signature" error.
Since I don't have a reference implementation, I'm struggling to figure out what's wrong with my code. I'm posting it here in the hope that somebody can spot my mistake.
public string GetAuthorizationHeader(string macKeyIdentifier, string macKey, string macAlgorithm, string method, Uri uri)
{
TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
string timestamp = ((int)t.TotalSeconds).ToString();
string nonce = new Random().Next().ToString();
string normalizedString = string.Format("{0}\n{1}\n{2}\n{3}\n{4}\n{5}\n\n",
timestamp,
nonce,
method,
uri.PathAndQuery,
uri.Host,
uri.Port);
HashAlgorithm hashGenerator = null;
if (macAlgorithm == "hmac-sha-256")
{
hashGenerator = new HMACSHA256(Encoding.ASCII.GetBytes(macKey));
}
else if (macAlgorithm == "hmac-sha-1")
{
hashGenerator = new HMACSHA1(Encoding.ASCII.GetBytes(macKey));
}
else
{
throw new InvalidOperationException("Unsupported MAC algorithm");
}
string hash = System.Convert.ToBase64String(hashGenerator.ComputeHash(Encoding.ASCII.GetBytes(normalizedString)));
StringBuilder authorizationHeader = new StringBuilder();
authorizationHeader.AppendFormat(#"id=""{0}"",ts=""{1}"",nonce=""{2}"",mac=""{3}""",
macKeyIdentifier, timestamp, nonce, hash);
return authorizationHeader.ToString();
}
I create the full header using the returned value and it looks something lke this
Authorization: MAC id="a:dfsdfa2",ts="1349277638",nonce="1469030797",mac="ibZ/HXaoz2VgBer3CK7K9vu0po3K+E36K+TQ9Sgcw6o="
I'm sure I'm missing something small, but I cannot see it.
Any help would be very much appreciated!
It turns out the code above is perfect, but I was passing the wrong HTTP method value into it!
Where I was getting the error, I was POST'ing JSON, but I had actually put "GET" into the GetAuthorizationMethod!
Once I'd corrected that, I got an access_token value from Tent.is.
Nicely executed tool at http://buchananweb.co.uk/security01.aspx showing HMAC using MD5 and SHA1, SHA256, SHA384, SHA512