I’m trying to login to https://www.interactivebrokers.com/sso/Login using a c# client. There’s a step that involves creating a sha1 hash from the username & password ( https://www.interactivebrokers.com/sso/Templates/javascript/myxyz.js , line 203):
innerHash = CalcSHA1(username + ":" + password);
this calls ( https://www.interactivebrokers.com/sso/Templates/javascript/sha1.js , line 113)
calcSHA1Blks(str2blks_SHA1(str);
and str2blks_SHA1() is defined ( https://www.interactivebrokers.com/sso/Templates/javascript/sha1.js , line 28) as
/*
* Convert a string to a sequence of 16-word blocks, stored as an array.
* Append padding bits and the length, as described in the SHA1 standard.
*/
function str2blks_SHA1(str)
{
var nblk = ((str.length + 8) >> 6) + 1;
var blks = new Array(nblk * 16);
for(var i = 0; i < nblk * 16; i++) blks[i] = 0;
for(i = 0; i < str.length; i++)
blks[i >> 2] |= str.charCodeAt(i) << (24 - (i % 4) * 8);
blks[i >> 2] |= 0x80 << (24 - (i % 4) * 8);
blks[nblk * 16 - 1] = str.length * 8;
return blks;
}
I’m not all that familiar with SHA1 stuff, so I can’t tell if what’s in str2blks_SHA1() is standard stuff that is done automatically inside .net’s SHA1CryptoServiceProvider.ComputeHash(), or if it’s something I need to do explicitly. I tried:
SHA1CryptoServiceProvider.ComputeHash(Encoding.UTF8.GetBytes(userName + ":" + password))
using the same username & password in javascript and in .net, and it seems to generate a different result.
Then I tried to port that str2blks_SHA1() function to c#, but I don’t understand how to create an array of bytes (blks) (which SHA1CryptoServiceProvider.ComputeHash() requires), as it seems like each array item in blks could be larger than a byte (just looking at str.length * 8))…
So, is there already some SHA1 implementation that does the same thing as this javascript implementation available? Or if I really do need to implement this myself, how do I port str2blks_SHA1()?
Thanks
This JavaScript implementation looks like the standard SHA-1 padding algorithm from RFC 3174. I get the same results (ignoring minor formatting differences) from running:
as I do from:
What data are you supplying and what (different) results are you getting?
(Note that if your username or password contain non-ASCII characters, I wouldn’t be surprised for the JavaScript to generate a different result than C#, because it doesn’t appear to be doing a proper UTF-8 conversion; specifically, it appears to assume that each character is just one byte.)