Try to convert HashPassword c# (Microsoft example) to javascript - javascript

I would like to convert byte.Parse in c# to javascript .. but i am not sure how.
byte[] binarySaltValue = new byte[SaltValueSize];
binarySaltValue[0] = byte.Parse(saltValue.Substring(0, 2), System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture.NumberFormat);
I need to get the ascII code of the substring(0,2) ... did i am right ?
EDIT QUESTION
The real think i try to do is to convert into Javascript the HashPassword method from Microsoft.
private static string HashPassword(string clearData, string saltValue, HashAlgorithm hash)
{
UnicodeEncoding encoding = new UnicodeEncoding();
if (clearData != null && hash != null && encoding != null)
{
// If the salt string is null or the length is invalid then
// create a new valid salt value.
// Convert the salt string and the password string to a single
// array of bytes. Note that the password string is Unicode and
// therefore may or may not have a zero in every other byte.
byte[] binarySaltValue = new byte[SaltValueSize];
binarySaltValue[0] = byte.Parse(saltValue.Substring(0, 2), System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture.NumberFormat);
binarySaltValue[1] = byte.Parse(saltValue.Substring(2, 2), System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture.NumberFormat);
binarySaltValue[2] = byte.Parse(saltValue.Substring(4, 2), System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture.NumberFormat);
binarySaltValue[3] = byte.Parse(saltValue.Substring(6, 2), System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture.NumberFormat);
byte[] valueToHash = new byte[SaltValueSize + encoding.GetByteCount(clearData)];
byte[] binaryPassword = encoding.GetBytes(clearData);
// Copy the salt value and the password to the hash buffer.
binarySaltValue.CopyTo(valueToHash, 0);
binaryPassword.CopyTo(valueToHash, SaltValueSize);
byte[] hashValue = hash.ComputeHash(valueToHash);
// The hashed password is the salt plus the hash value (as a string).
string hashedPassword = saltValue;
foreach (byte hexdigit in hashValue)
{
hashedPassword += hexdigit.ToString("X2", CultureInfo.InvariantCulture.NumberFormat);
}
// Return the hashed password as a string.
return hashedPassword;
}
return null;
}

Ok so there is my solution, maybe it's not optimized but working fine!
function Salt(plainText, salt) {
if (plainText != undefined && plainText != "" && salt != null) {
// If the salt string is null or the length is invalid then
// create a new valid salt value.
// Convert the salt string and the password string to a single
// array of bytes. Note that the password string is Unicode and
// therefore may or may not have a zero in every other byte.
var binarySaltValue = new Array();
binarySaltValue[0] = parseInt(salt.substring(0, 2), 16);
binarySaltValue[1] = parseInt(salt.substring(2, 4), 16);
binarySaltValue[2] = parseInt(salt.substring(4, 6), 16);
binarySaltValue[3] = parseInt(salt.substring(6, 8), 16);
var binaryPassword = cryptoHelper.stringToBytes(plainText);
var valueToHash = new Array();
// Copy the salt value and the password to the hash buffer.
// binarySaltValue.concat(valueToHash);
// binarySaltValue.CopyTo(valueToHash, 0);
// binaryPassword.CopyTo(valueToHash, SaltValueSize);
valueToHash = valueToHash.concat(binarySaltValue);
// Détermine la longeur utilisé par le array - 2048
var newLengthArray = 2048 - valueToHash.length;
var tampon = new Array(newLengthArray);
for (var i = 0; i < tampon.length; i++) {
tampon[i] = 0;
}
valueToHash = valueToHash.concat(tampon);
valueToHash = valueToHash.concat(binaryPassword);
var hashValue = CryptoJS.MD5(CryptoJS.lib.Base.ByteArray(valueToHash));
var arr = wordArrayToByteArray(hashValue);
var hashedPassword = salt;
for (var i = 0; i < arr.length; i++) {
hexdigit = arr[i];
var hexValue = hexdigit.toString(16);
if (hexValue.length < 2) hexValue = "0" + hexValue;
hashedPassword += hexValue;
}
return hashedPassword;
}
return null;
}

Related

Convert Java's PBEWithMD5AndDES without salt to JavaScript with crypto

I have the following code for decryption in java, I want that to be implemented in nodejs but the i found many tuto for my problem but they use a salt and that don't work when i try to remove the salt system.
My olds functions from java
public void readLastLogin(File lastLogin) {
try {
final Cipher ciph = this.openCipher(Cipher.DECRYPT_MODE);
final DataInputStream dis = new DataInputStream(new CipherInputStream(new FileInputStream(lastLogin), ciph));
String user = dis.readUTF();
String token = dis.readUTF();
dis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void saveLastLogin(File lastLogin, String user, String token) {
try {
final Cipher ciph = this.openCipher(Cipher.ENCRYPT_MODE);
final DataOutputStream dos = new DataOutputStream(new CipherOutputStream(new FileOutputStream(lastLogin), ciph));
dos.writeUTF(user);
dos.writeUTF(token);
dos.close();
} catch (final Exception e) {
e.printStackTrace();
}
}
private Cipher openCipher(final int mode) throws Exception {
final Random rnd = new Random(43287234L);
final byte[] data = new byte[8];
rnd.nextBytes(data);
final PBEParameterSpec spec = new PBEParameterSpec(data, 5);
final SecretKey key = SecretKeyFactory
.getInstance("PBEWithMD5AndDES")
.generateSecret(new PBEKeySpec("mysecretpassword".toCharArray()));
final Cipher ret = Cipher.getInstance("PBEWithMD5AndDES");
ret.init(mode, key, spec);
return ret;
}
I try this but not working
KDF(password, iterations) {
var key = new Buffer(password,'utf-8');
var i;
for (i = 0; i < iterations; i+=1) {
key = crypto.createHash("md5").update(key).digest();
}
return key;
}
getKeyIV(password, iterations) {
var key = this.KDF(password, iterations);
var keybuf = new Buffer(key,'binary').slice(0,8);
var ivbuf = new Buffer(key,'binary').slice(8,16);
return [ keybuf, ivbuf ];
}
decrypt(message) {
var kiv = this.getKeyIV('password' ,5);
var decipher = crypto.createDecipheriv('des-ede', kiv[0], kiv[1]);
var result = decipher.update(message, 'hex', 'utf-8');
return result + decipher.final('utf-8');
}
Edit: The salt generated at runtime of the Java code is hex encoded: 0x0C9D4AE41E8315FC
final byte[] data = new byte[8];
data[0] = 12;
data[1] = -99;
data[2] = 74;
data[3] = -28;
data[4] = 30;
data[5] = -125;
data[6] = 21;
data[7] = -4;
There are three issues in the code:
The Java code uses writeUTF(). This is based on modified UTF-8, with two additional bytes prepended to contain the data size. A NodeJS library for modified UTF-8 is mutf-8.
Instead of des-ede (3DES/2TDEA in ECB mode), des-cbc (DES in CBC mode) must be applied. If DES is not available in the used NodeJS version, it can be mimicked with 3DES/2TDEA in CBC mode, des-ede-cbc, where the 8 bytes key has to be concatenated with itself to a 16 bytes key, reducing 3DES to DES. This workaround has the disadvantage of a performance loss.
The Java code applies a static 8 byte salt because Random() is instantiated with a static seed. This salt can be determined at runtime to (hex encoded): 0x0C9D4AE41E8315FC.
pbewithmd5anddes-js is a port of PBEWithMD5AndDES to NodeJS, from which the KDF(), getKeyIV() and decrypt() methods can be used, but must be adapted taking into account the above points. In addition, the functionality of readUTF() (the counterpart of writeUTF()) must be implemented. One possible solution is:
var crypto = require('crypto');
const { MUtf8Decoder } = require("mutf-8");
var pbewithmd5anddes = {
KDF: function(password,salt,iterations) {
var pwd = Buffer.from(password,'utf-8');
var key = Buffer.concat([pwd, salt]);
var i;
for (i = 0; i < iterations; i+=1) {
key = crypto.createHash('md5').update(key).digest();
}
return key;
},
getKeyIV: function(password,salt,iterations) {
var key = this.KDF(password,salt,iterations);
var keybuf = Buffer.from(key,'binary').subarray(0,8);
var ivbuf = Buffer.from(key,'binary').subarray(8,16);
return [ keybuf, ivbuf ];
},
decrypt: function(payload,password,salt,iterations) {
var encryptedBuffer = Buffer.from(payload,'base64');
var kiv = this.getKeyIV(password,salt,iterations);
//var decipher = crypto.createDecipheriv('des-cbc', kiv[0], kiv[1]); // Fix 1: If supported, apply DES-CBC with key K
var decipher = crypto.createDecipheriv('des-ede-cbc', Buffer.concat([kiv[0], kiv[0]]), kiv[1]); // otherwise DES-EDE-CBC with key K|K
var decryptedBuf = Buffer.concat([decipher.update(encryptedBuffer), decipher.final()])
var decrypted = this.readUTF(decryptedBuf) // Fix 2: apply writeUTF counterpart
return decrypted;
},
readUTF: function(decryptedBuf) {
var decoder = new MUtf8Decoder()
var decryptedData = []
var i = 0;
while (i < decryptedBuf.length){
var lengthObj = decryptedBuf.readInt16BE(i);
var bytesObj = decryptedBuf.subarray(i+2, i+2+lengthObj);
var strObj = decoder.decode(bytesObj)
decryptedData.push(strObj)
i += 2 + lengthObj;
}
return decryptedData;
}
};
Test:
On the Java side, the following is executed:
saveLastLogin(file, "This is the first plaintext with special characters like §, $ and €.", "This is the second plaintext with special characters like §, $ and €.");
The raw ciphertext written to file is Base64 encoded:
Ow8bdeNM0QpNFQaoDe7dhG3k9nWz/UZ6v3+wQVgrD5QvWR/4+sA+YvqtnQBsy35nQkwhwGRBv1h1eOa587NaFtnJUWVHsRsncLWZ05+dD2rYVpcZRA8s6P2iANK6yLr+GO/+UpZpSe0fA4fFqEK1nm3U7NXdyddfuOlZ3h/RiyxK5819LieUne4F8/TpMzT0RIWkxqagbVw=
This can be decrypted on the NodeJS side with:
var payload = 'Ow8bdeNM0QpNFQaoDe7dhG3k9nWz/UZ6v3+wQVgrD5QvWR/4+sA+YvqtnQBsy35nQkwhwGRBv1h1eOa587NaFtnJUWVHsRsncLWZ05+dD2rYVpcZRA8s6P2iANK6yLr+GO/+UpZpSe0fA4fFqEK1nm3U7NXdyddfuOlZ3h/RiyxK5819LieUne4F8/TpMzT0RIWkxqagbVw=';
var password = 'mysecretpassword';
var salt = Buffer.from('0C9D4AE41E8315FC', 'hex');
var iterations = 5;
var decrypted = pbewithmd5anddes.decrypt(payload,password,salt,iterations);
console.log(decrypted);
with the output:
[
'This is the first plaintext with special characters like §, $ and €.',
'This is the second plaintext with special characters like §, $ and €.'
]
Note that the code contains serious vulnerabilities:
PBEWithMD5AndDES uses a key derivation based on the broken MD5 digest (PBKDF1), and as encryption algorithm the deprecated DES (officially withdrawn almost 20 years ago).
Use of a static salt.
An iteration count of 5 is generally much too small.
Random() (unlike SecureRandom()) is not cryptographically strong. Also note that it is not a good idea to use a PRNG like Random() for deterministic key derivation, as the implementation may change, leading to different results even with the same seed.

How to encrypt AES in C# with CryptoJS [duplicate]

I'm triying to Encrypt string with C# and decrypt it using Angular crypto-js library but it's giving me different output.
I tried different c# aes encryption implementations but crypto-js library can't decrypt the encrypted data in c#. Thank you for any help.
Here is my code
Program.cs
static void Main()
{
var r = EncryptString("exampleString", "examplePassword");
Console.Write(r);
}
public static string EncryptString(string plainText, string passPhrase)
{
if (string.IsNullOrEmpty(plainText))
{
return "";
}
// generate salt
byte[] key, iv;
var salt = new byte[8];
var rng = new RNGCryptoServiceProvider();
rng.GetNonZeroBytes(salt);
DeriveKeyAndIv(passPhrase, salt, out key, out iv);
// encrypt bytes
var encryptedBytes = EncryptStringToBytesAes(plainText, key, iv);
// add salt as first 8 bytes
var encryptedBytesWithSalt = new byte[salt.Length + encryptedBytes.Length + 8];
Buffer.BlockCopy(Encoding.ASCII.GetBytes("Salted__"), 0, encryptedBytesWithSalt, 0, 8);
Buffer.BlockCopy(salt, 0, encryptedBytesWithSalt, 8, salt.Length);
Buffer.BlockCopy(encryptedBytes, 0, encryptedBytesWithSalt, salt.Length + 8, encryptedBytes.Length);
// base64 encode
return Convert.ToBase64String(encryptedBytesWithSalt);
}
private static void DeriveKeyAndIv(string passPhrase, byte[] salt, out byte[] key, out byte[] iv)
{
// generate key and iv
var concatenatedHashes = new List<byte>(48);
var password = Encoding.UTF8.GetBytes(passPhrase);
var currentHash = new byte[0];
var md5 = MD5.Create();
bool enoughBytesForKey = false;
// See http://www.openssl.org/docs/crypto/EVP_BytesToKey.html#KEY_DERIVATION_ALGORITHM
while (!enoughBytesForKey)
{
var preHashLength = currentHash.Length + password.Length + salt.Length;
var preHash = new byte[preHashLength];
Buffer.BlockCopy(currentHash, 0, preHash, 0, currentHash.Length);
Buffer.BlockCopy(password, 0, preHash, currentHash.Length, password.Length);
Buffer.BlockCopy(salt, 0, preHash, currentHash.Length + password.Length, salt.Length);
currentHash = md5.ComputeHash(preHash);
concatenatedHashes.AddRange(currentHash);
if (concatenatedHashes.Count >= 48)
enoughBytesForKey = true;
}
key = new byte[32];
iv = new byte[16];
concatenatedHashes.CopyTo(0, key, 0, 32);
concatenatedHashes.CopyTo(32, iv, 0, 16);
md5.Clear();
}
static byte[] EncryptStringToBytesAes(string plainText, byte[] key, byte[] iv)
{
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (key == null || key.Length <= 0)
throw new ArgumentNullException("key");
if (iv == null || iv.Length <= 0)
throw new ArgumentNullException("iv");
// Declare the stream used to encrypt to an in memory
// array of bytes.
MemoryStream msEncrypt;
// Declare the RijndaelManaged object
// used to encrypt the data.
RijndaelManaged aesAlg = null;
try
{
// Create a RijndaelManaged object
// with the specified key and IV.
aesAlg = new RijndaelManaged { Mode = CipherMode.CBC, KeySize = 256, BlockSize = 128, Key = key, IV = iv };
// Create an encryptor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for encryption.
msEncrypt = new MemoryStream();
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (var swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
swEncrypt.Flush();
swEncrypt.Close();
}
}
}
finally
{
// Clear the RijndaelManaged object.
aesAlg?.Clear();
}
// Return the encrypted bytes from the memory stream.
return msEncrypt.ToArray();
}
Simply decrypting it using crypto-js
let CryptoJS = require('crypto-js');
let r = CryptoJS.AES.decrypt('exampleString', 'examplePassword').toString();
The example code is attempting to decrypt the original unencrypted string, which looks to be a mistake perhaps created when trying to simplify the example code for posting the question? Either way the steps required are not too difficult, but the toString() call needs to be replaced.
var data = "U2FsdGVkX1/Zvh/5BnLfUgfbg5ROSD7Aohumr9asPM8="; // Output from C#
let r2 = CryptoJS.enc.Utf8.stringify(CryptoJS.AES.decrypt(data, 'examplePassword'));
console.log(r2);

Replication of HMACSHA256 in c# as that of jsSHA

so i am trying to get this hash 69F6617707D9442940C39BEBFA0B4459CEBF6CD5E610EA1FF44B341E291654A9 which can me made on https://caligatio.github.io/jsSHA/.
The key is K = E74A540FA07C4DB1B46421126DF7AD36 , Message is T= 537707AD486F07AD75CCF7B1F7FEA6F75871FCF6DC755923C8EE7C375C21EAC51BD97C51C69F395B and the generated hash via my code is SHA256 (T) = 6a2783d8eb0237e015f7dcd27fb2d2a85dd637220433dffcdc31198670f6ecac
This is incorrect Hash.
This is my code can someone explain what is wrong here thanks.
static void Main(string[] args)
{
var key = "E74A540FA07C4DB1B46421126DF7AD36";
string message = "537707AD486F07AD75CCF7B1F7FEA6F75871FCF6DC755923C8EE7C375C21EAC51BD97C51C69F395B";
var encodingCred = new System.Text.ASCIIEncoding();
var encodingKey = new System.Text.ASCIIEncoding();
byte[] keyByte = StringToByteArray(key);
byte[] credentialsBytes = encodingCred.GetBytes(message);
using (var hmacsha256 = new HMACSHA256(keyByte))
{
byte[] hashmessage = hmacsha256.ComputeHash(credentialsBytes);
string hash = BitConverter.ToString(hashmessage).Replace("-", string.Empty).ToLower();
Console.WriteLine("HASH: " + hash);
}
Console.ReadKey();
}
public static byte[] StringToByteArray(String hex)
{
int NumberChars = hex.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
return bytes;
}
In C this is valid
void test_keyed_hmac()
{
hmac_sha256 hmac;
sha256 sha;
uint8_t sha_digest[32] = { 0 };
unsigned char key[] = "\xE7\x4A\x54\x0F\xA0\x7C\x4D\xB1\xB4\x64\x21\x12\x6D\xF7\xAD\x36";
//unsigned char key[] = "E74A540FA07C4DB1B46421126DF7AD36";
unsigned char data[] = "\x53\x77\x07\xAD\x48\x6F\x07\xAD\x75\xCC\xF7\xB1\xF7\xFE\xA6\xF7\x58\x71\xFC\xF6\xDC\x75\x59\x23\xC8\xEE\x7C\x37\x5C\x21\xEA\xC5\x1B\xD9\x7C\x51\xC6\x9F\x39\x5B";
//unsigned char data[] = "537707AD486F07AD75CCF7B1F7FEA6F75871FCF6DC755923C8EE7C375C21EAC51BD97C51C69F395B";
printf("Data length %d \n", strlen(data));
hmac_sha256_initialize(&hmac, key, strlen(key));
// Finalize the HMAC-SHA256 digest and output its value.
hmac_sha256_finalize(&hmac, data, strlen(data));
for (int i = 0; i < 32; ++i) {
// Cast added by RKW to get format specifier to work as expected
printf("%x", (unsigned long)hmac.digest[i]);
}
putchar('\n');
}
I need something like this in c# that gives the valid hash mentioned above in second line

Invalid Array Length in using Cryptojs

I am trying to transpose a c# code to a javascript using cryptojs and in the c# code it uses TripleDESCryptoServiceProvider. I can get everything exactly the values of C# in my javascript code except for the encrypting part. I get an error of "Invalid array length" This is the whole error message:
"RangeError: Invalid array length
at WordArray.init.clamp (http://localhost:8100/auth-login-login-module.js:1392:27)
at WordArray.init.concat (http://localhost:8100/auth-login-login-module.js:1357:19)
at Object.pad (http://localhost:8100/auth-login-login-module.js:652:19)
at Object._doFinalize (http://localhost:8100/auth-login-login-module.js:729:26)
at Object.finalize (http://localhost:8100/auth-login-login-module.js:400:44)
at Object.encrypt (http://localhost:8100/auth-login-login-module.js:912:41)
at Object.encrypt (http://localhost:8100/auth-login-login-module.js:438:59)
at AuthService.encryptText (http://localhost:8100/auth-login-login-module.js:6745:83)
at LoginPage.ngOnInit (http://localhost:8100/auth-login-login-module.js:6939:26)
at checkAndUpdateDirectiveInline (http://localhost:8100/vendor.js:65455:19)"
Please see my code on c# and javascript.
C#
public static string EncryptTxt(string key, string msg, CipherMode mode, Int16 KeyOffSet)
{
SHA512CryptoServiceProvider sha = new SHA512CryptoServiceProvider();
byte[] newKey = new byte[23];
using (var tdes = new TripleDESCryptoServiceProvider())
{
byte[] Results;
System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(key));
TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();
byte[] keybyte = sha.ComputeHash(Encoding.UTF8.GetBytes(key));
byte[] newKeyx = new byte[24];
Array.Copy(keybyte, KeyOffSet, newKeyx, 0, newKeyx.Length);
TDESAlgorithm.Key = newKeyx;
TDESAlgorithm.Mode = mode;
TDESAlgorithm.Padding = PaddingMode.PKCS7;
byte[] DataToEncrypt = UTF8.GetBytes(msg);
try
{
ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor();
Results = Encryptor.TransformFinalBlock(DataToEncrypt, 0, DataToEncrypt.Length);
}
finally
{
TDESAlgorithm.Clear();
HashProvider.Clear();
}
return Convert.ToBase64String(Results);
}
javascript
encryptText = () => {
debugger;
const msg = 'xxx:juan:201910181809:12345678';
let key = crypto.enc.Utf8.parse('xxx');
key = crypto.MD5(key);
key.words.push(key.words[0], key.words[1]);
const iv = crypto.enc.Utf8.parse('xxx');
// MD5CryptoServiceProvider
const hashProvider = crypto.MD5(iv);
const TDESKey = this.wordArrayToByteArray(hashProvider, 8);
const keybyte = this.wordArrayToByteArray(crypto.SHA512(iv), 16);
const newKeyx = new Uint8Array(24);
const newkeybyte = keybyte.slice(10, 34);
Object.assign(newKeyx, newkeybyte);
const TDESAlgorithmKey = newkeybyte;
const DataToEncrypt = this.wordArrayToByteArray(crypto.enc.Utf8.parse(msg), 40);
const dteLength = DataToEncrypt.length;
const encrypted = crypto.TripleDES.encrypt(DataToEncrypt, key, {
keySize: dteLength,
mode: crypto.mode.ECB,
padding: crypto.pad.Pkcs7,
algo: TDESAlgorithmKey
});
const result = this.wordArrayToByteArray(encrypted.ciphertext, dteLength);
console.log(encrypted);
return encrypted;
}
wordToByteArray(word: any, length: any) {
const ba = [], xFF = 0xFF;
if (length > 0) {
// tslint:disable-next-line:no-bitwise
ba.push(word >>> 24);
}
if (length > 1) {
// tslint:disable-next-line:no-bitwise
ba.push((word >>> 16) & xFF);
}
if (length > 2) {
// tslint:disable-next-line:no-bitwise
ba.push((word >>> 8) & xFF);
}
if (length > 3) {
// tslint:disable-next-line:no-bitwise
ba.push(word & xFF);
}
return ba;
}
Can you please show me how to do this right. I really appreciate it!
This error is triggered when you pass an object (other data type rather than a string).
Convert your parameter to string before passing it ahead.
Try using JSON.stringify(), let me know if it works ..

how to recreate the .net membership hmacsha1 hash in javascript

I'm trying to reproduce the same hmacsha1 hash and base64 encoding from .net membership provider in a javascript function. I've tried using crypto-js and am getting different results. The .net code will hash "test" into "W477AMlLwwJQeAGlPZKiEILr8TA="
Here's the .net code
string password = "test";
HMACSHA1 hash = new HMACSHA1();
hash.Key = Encoding.Unicode.GetBytes(password);
string encodedPassword = Convert.ToBase64String(hash.ComputeHash(Encoding.Unicode.GetBytes(password)));
And here's the javascript method I tried using crypto-js that does not produce the same output
var hash = CryptoJS.HmacSHA1("test", "");
var encodedPassword = CryptoJS.enc.Base64.stringify(hash);
How can I get my javascript hash to match the hash being generated from .net.
//not sure why crypt-js's utf16LE function doesn't give the same result
//words = CryptoJS.enc.Utf16LE.parse("test");
//utf16 = CryptoJS.enc.Utf16LE.stringify("test");
function str2rstr_utf16le(input) {
var output = [],
i = 0,
l = input.length;
for (; l > i; ++i) {
output[i] = String.fromCharCode(
input.charCodeAt(i) & 0xFF,
(input.charCodeAt(i) >>> 8) & 0xFF
);
}
return output.join('');
}
var pwd = str2rstr_utf16le("test");
var hash = CryptoJS.HmacSHA1(pwd, pwd);
var encodedPassword = CryptoJS.enc.Base64.stringify(hash);
alert(encodedPassword);
You don't specify a key in .NET:
var secretKey = "";
var password = "test";
var enc = Encoding.ASCII;
System.Security.Cryptography.HMACSHA1 hmac = new System.Security.Cryptography.HMACSHA1(enc.GetBytes(secretKey));
hmac.Initialize();
byte[] buffer = enc.GetBytes(password);
var encodedPassword = Convert.ToBase64String(hmac.ComputeHash(buffer));
Edit: as #Andreas mentioned, your problem is the encoding. So you just need to replace UTF by ANSI in your own code:
string password = "test";
System.Security.Cryptography.HMACSHA1 hash = new System.Security.Cryptography.HMACSHA1();
hash.Key = Encoding.ASCII.GetBytes("");
string encodedPassword = Convert.ToBase64String(hash.ComputeHash(Encoding.ASCII.GetBytes(password)));

Categories