Twitter HMACSHA1 Signature Creation C# - c#

I am trying to implement Twitter sign in via C# & I am getting a 401 Unauthorized error - "Could not authenticate you" which isn't that helpful. To try to diagnose the problem I want to make sure that the signature creation is working correctly.
Twitter's documentation page for signature creation is here. I have written a simple unit test that should generate a signature based on the values specified in the documentation. However the test fails as I get a different signature string. Are the values in the documentation wrong or is is#t the code I'm using? However all the C# Twitter code I've seen uses similar hashing code.
[TestMethod]
public void TwitterSignatureCreation() {
var signingKey = "kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw&LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE";
var baseString = "POST&https%3A%2F%2Fapi.twitter.com%2F1.1%2Fstatuses%2Fupdate.json&include_entities%3Dtrue%26oauth_consumer_key%3Dxvz1evFS4wEEPTGEFPHBog%26oauth_nonce%3DkYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1318622958%26oauth_token%3D370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb%26oauth_version%3D1.0%26status%3DHello%2520Ladies%2520%252B%2520Gentlemen%252C%2520a%25";
var hmac = new HMACSHA1( Encoding.ASCII.GetBytes( signingKey ) );
var hash = hmac.ComputeHash( Encoding.ASCII.GetBytes( baseString ) );
var signatureString = Convert.ToBase64String( hash );
var expectedSignatureString = "hCtSmYh+iHYCEqBWrE7C7hYmtUk=";
Assert.AreEqual( expectedSignatureString, signatureString );
}
Assert.AreEqual failed.
Expected:<hCtSmYh+iHYCEqBWrE7C7hYmtUk=>.
Actual:<hOhJgzPMpZtXHCTeluIS1VdHUH8=>.

Related

How do you verify a signature originated from a given Tezos wallet?

After connecting to a Tezos wallet, you can send over a payload requesting it be signed.
Given the signature, wallet address, and a pre-defined message (payload) what are the steps to determine the authenticity of that signature.
You can do that in C# using Netezos library.
First, you need to obtain the public key for a given wallet address:
using Netezos.Rpc;
using var rpc = new TezosRpc("https://mainnet-tezos.giganode.io/");
var rawPubKey = await rpc.Blocks.Head.Context.Contracts[address].ManagerKey.GetAsync<string>();
Then you can verify the signature:
using Netezos.Keys;
var pubKey = PubKey.FromBase58(rawPubKey);
var isValid = pubKey.Verify(message, signature);
import { verifySignature } from '#taquito/utils';
verifySignature(
payloadBytes,
publicKey,
updateAatarLinkDto.signature,
);
You need to include payloadBytes and signature to verify.

C# sending data using JWT in MVC when private key is from a pfx

This is my first implementation of using JWT in MVC. I have created the following token in my controller to pass to the front end when they hit my endpoint . I have used the tool on JWT.io but I am uncertain if it's worked and what I put in the signature section 'secret'. It says invalid token signature but I can see the payload. Here is the code:
Any help or pointing in the right direction to see how it works would be great.
var payload = new Dictionary<string, object>()
{
{ "id", "example123" },
{ "Name", "John Doe" }
};
X509Certificate2 certX509 = new X509Certificate2(pfxFile, password);
byte[] privateKey = certX509.Export(X509ContentType.Cert, password);
string token = Jose.JWT.Encode(payload, privateKey, JwsAlgorithm.HS256);
//string[] getSecret = token.Split(".".ToCharArray());
//secret = getSecret[2];
return token;
The result, which seems to look like a JWT token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImV4YW1wbGUxMjMiLCJOYW1lIjoiSm9obiBEb2UifQ.j4Ub0iWU-6xTbc3pvwfBy0v0o-Y2Ds6C5_ez3NIRnIk
but it doesn't validate on https://jwt.io/. Thank you in advance :)
Edit
After playing around more I found if I create a string then convert it to a byte array then use the text in the signature box it verifies!!. Because my current byte array is populated from a pfx, the value to enter is unknown.
Put private key on secret textbox. correct secret validate token.
see snap

IoT-Core UWP MacAlgorithmProvider vs.NET 4.5 HMACSHA256 usage giving 403

Identical code except for the CreateAuthenticationHeader functions below. In .Net 4.5 MVC5 I can REST-access (REST, no storage library) an azure table without difficulty using this:
private static string CreateAuthorizationHeader(string canonicalizedString)
{
var sharedKeyParts = SvcComsCommon.AzureStorageConnectStringDict();
var signature = string.Empty;
using (HMACSHA256 hmacSha256 = new HMACSHA256(Convert.FromBase64String(sharedKeyParts["AccountKey"])))
{
var dataToHmac = System.Text.Encoding.UTF8.GetBytes(canonicalizedString);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}
var account = sharedKeyParts["AccountName"];
var authorizationHeader = string.Format(
CultureInfo.InvariantCulture,
"{0} {1}:{2}",
"SharedKey",
account,
signature);
return authorizationHeader;
}
On Windows IoT-Core (UWP) newest from Oct. 2015 I use the following (since the above is not supported), which gives me a 403 error and complains that my signature is wrong. The rest of the code is identical. What is the nuance I am missing?
private static string CreateAuthorizationHeader(string canonicalizedString)
{
var sharedKeyParts = SvcComsCommon.AzureStorageConnectStringDict(); // Just the Azure Storage Connection String as Dictionary. No tricks.
var key = CryptographicBuffer.ConvertStringToBinary(sharedKeyParts["AccountKey"], BinaryStringEncoding.Utf8);
var msg = CryptographicBuffer.ConvertStringToBinary(canonicalizedString, BinaryStringEncoding.Utf8);
// Create HMAC.
var objMacProv = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha256);
var hash = objMacProv.CreateHash(key);
hash.Append(msg);
var signature = CryptographicBuffer.EncodeToBase64String(hash.GetValueAndReset());
// Header
var account = sharedKeyParts["AccountName"];
var authorizationHeader = string.Format(
CultureInfo.InvariantCulture,
"{0} {1}:{2}",
"SharedKey",
account,
signature);
return authorizationHeader;
}
I've read the other posts, still not seeing what is missing.
Update Error message on IoT-Core RPi ARM
The operation identifier is not valid.
at SharedLibrary!<BaseAddress>+0x8d1eb9
at SharedLibrary!<BaseAddress>+0xd0e30b
at SharedLibrary!<BaseAddress>+0xd0e7af
at SharedLibrary!<BaseAddress>+0xd0e715
at SharedLibrary!<BaseAddress>+0xd0e69f
at RpiHeadlessCS.Devices.HxaRs485Ftdi.<ReadAsync>d__26.MoveNext()
Exception thrown: 'System.Exception' in RpiHeadlessCS-uwp.Interop.dll
Read async error: The operation identifier is not valid.
UWP has a bug in the framework pertaining to caching behavior that causes Auth errors for Azure Storage. They're working on a fix, but I'm not 100% sure when that fix will be deployed. Sorry about that!

Could you explain the little difference between my two hash?

I'm trying to implement a WCF OAuth restful Web API service.
Without knowing the code could you explain the little difference between my two hash:
dictionary["oauth_signature"] "URirekG5i5MbWxoinc4bi4H8j1g%3D" string
hash "URirekG5i5MbWxoinc4bi4H8j1g=" string
I use RESTClient (firefox addon) to test my WCF OAuth restful Web API service. I followed this article.
It seems something is added to the end of dictionary["oauth_signature"] or something is missing in my generated hash. But what?
if (dictionary["oauth_consumer_key"] != null)
{
// to get uri without oauth parameters
string uri = context.UriTemplateMatch.RequestUri.ToString();
string consumersecret = "suryabhai";
OAuthBase oauth = new OAuthBase();
string hash = oauth.GenerateSignature(
new Uri(uri),
dictionary["oauth_consumer_key"],
consumersecret,
null, // totken
null, //token secret
"GET",
dictionary["oauth_timestamp"],
dictionary["oauth_nonce"],
out normalizedUrl,
out normalizedRequestParameters
);
Authenticated = dictionary["oauth_signature"] == hash;
}
return Authenticated;
Somewhere in your application, your hash got URL encoded. That means that the = sign, a special character in URLs, was encoded to %3D. If you decode it, they will match.

How to generate oauth_signature intuit ipp QBO API V3

I am having some issues with limitations of the .NET SDK and so would like to issue my own calls to the API and parse the JSON results. I am stuck on creating the authorization header parameter oauth_signature as outlined here.
For this parameter it states: Contains the value generated by running all other request parameters and two secret values through a signing algorithm
Does the "two secret values" refer to the OAuthAccessTokenSecret and the consumerSecret?
Does "all other request parameters" mean just those parameter values? Concatenated?
How do you use 2 secret values in an and HMACSHA1 signing algorithm? All examples I see just use one
What I have so far.
public static string GetOAuthAuthorization(string oauthToken, string oauthSecret, string consumerKey, string consumerSecret)
{
string oauth_token = oauthToken;
string oauth_nonce = Guid.NewGuid().ToString();
string oauth_consumer_key = consumerKey;
string oauth_signature_method = "HMAC-SHA1";
int oauth_timestamp = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
string oauth_version="1.0";
string dataString = oauth_token + oauth_nonce + oauth_consumer_key + oauth_timestamp;
//TODO: use following to create oauth_signature
byte[] hashkey = Encoding.ASCII.GetBytes(oauthSecret); //is this one of the secret values?
byte[] data = Encoding.ASCII.GetBytes(dataString);
HMACSHA1 hmac = new HMACSHA1(hashkey);
byte[] result = hmac.ComputeHash(data);
string oauth_signature=Convert.ToBase64String(result);
return string.Format("OAuth oauth_token='{0}',oauth_nonce='{1}',oauth_consumer_key='{2}',oauth_signature_method='{3}',oauth_timestamp='{4}',oauth_version='{5}',oauth_signature='{6}'",
oauth_token, oauth_nonce, oauth_consumer_key, oauth_signature_method,oauth_timestamp,oauth_version, oauth_signature
);
}
Please check the sample app provided by Intuit for V3. This is already implemented. You can set in your keys and debug-
https://github.com/IntuitDeveloperRelations/
When you had generated an app with IPP, you must have got a consumer key and consumer secret.
That is what is being referred in the line you have mentioned.
https://developer.intuit.com/docs/0025_quickbooksapi/0010_getting_started
For other questions, just debug the sample code after setting in your app keys in web.config, you will get the answers.

Categories