Replication of HMACSHA256 in c# as that of jsSHA - javascript

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

Related

Java and JavaScript hash with SHA-256 difference result

I do hash from Java and Compare with Java Script Code using same SHA-256 but the result seem different. Did anyone know help me on these please. Here is the code below.
Java Code
private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
private static String salt = "Apple#987";
private static byte[] saltArr = salt.getBytes();
public static String getSHA256(String data) {
StringBuilder sb = new StringBuilder();
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(saltArr);
byte[] byteData = md.digest(data.getBytes());
sb.append(bytesToHex(byteData));
} catch(Exception e) {
e.printStackTrace();
}
return sb.toString();
}
private static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return String.valueOf(hexChars);
}
String hashed = getSHA256("SampleData");
System.out.println("hashed");
Java Script Code (In Postman)
var salt = 'Apple#987';
var data = 'SampleData';
var hash = CryptoJS.HmacSHA256(data, salt).toString(CryptoJS.enc.Hex);
Java Result:
7B2BBE6DAD962170A83A911EE7B84A382DE2F7FA0DA77C55F99F696EEFAF6C5D
Java Script Result:
1de0de12c5f22bf98f2dbae8430470cac64875a28a035191c3f783e6a2d6cb3b
the Javascript result(1de0de12c5f22bf98f2dbae8430470cac64875a28a035191c3f783e6a2d6cb3b) is right,check it in this link
Java Code you can refer this link
String key = "Apple#987";
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
sha256_HMAC.init(new SecretKeySpec(key.getBytes(), "HmacSHA256"));
byte[] result = sha256_HMAC.doFinal("SampleData".getBytes());
System.out.println (DatatypeConverter.printHexBinary(result));
javascript code:
var result = crypto.createHmac('SHA256', 'Apple#987').update('SampleData').digest('hex')
console.log(result)
thanks.

AES-256(CBC) : encryption in Java/Decryption in JavaScript(CryptoJS)

I am doing encryption in Java and decrypting it with JavaScript using AES-256/CBC, but actually this is the scenario:
while encryption of .pdf, .jpg, in other words, other than text files Java produces the encrypted file with roughly the same bytes but in case of JavaScript(CryptoJS) it outputs ~1.5 times of the original file size, which is why I think for the decryption with CryptoJS it does not expect the small encrypted file size from Java. I have given the code from both sides i.e, encryption at Java side, decryption at JavaScript side.
Problem:
I have a requirement of encrypting any file with Java and decrypting the same file with JavaScript. Kindly refer to the code as given below and this example.
Java: Encryption
key generation:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), hex(salt), iterationCount, keySize);
SecretKey key = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
Encryption:
params:
private static final String IV = "F27D5C9927726BCEFE7510B1BDD3D137";
private static final String SALT = "3FF2EC019C627B945225DEBAD71A01B6985FE84C95A70EB132882F88C0A59A55";
private static final int KEY_SIZE = 128;
private static final int ITERATION_COUNT = 10000;
private static final String PASSWORD = "SET_YOUR_PASSWORD_HERE";
code:
public String encrypt(String salt, String iv, String passphrase, String plaintext) {
try {
SecretKey key = generateKey(salt, passphrase);
byte[] encrypted = doFinal(Cipher.ENCRYPT_MODE, key, iv, plaintext.getBytes("UTF-8"));
return base64(encrypted);
} catch (Exception e) {
throw fail(e);
}
}
private byte[] doFinal(int encryptMode, SecretKey key, String iv, byte[] bytes) {
try {
cipher.init(encryptMode, key, new IvParameterSpec(hex(iv)));
return cipher.doFinal(bytes);
} catch (InvalidKeyException |
InvalidAlgorithmParameterException |
IllegalBlockSizeException |
BadPaddingException e) {
throw fail(e);
}
}
public static String base64(byte[] bytes) {
return Base64.getEncoder().encodeToString(bytes);
}
public static byte[] base64(String str) {
return Base64.getDecoder().decode(str);
}
protected static byte[] hex(String str) {
try {
return decodeHex(str.toCharArray());
} catch (Exception e) {
e.printStackTrace();
}
return new byte[0];
}
public static byte[] decodeHex(char[] data) throws Exception {
int len = data.length;
if ((len & 1) != 0) {
throw new Exception("Odd number of characters.");
} else {
byte[] out = new byte[len >> 1];
int i = 0;
for (int j = 0; j < len; ++i) {
int f = toDigit(data[j], j) << 4;
++j;
f |= toDigit(data[j], j);
++j;
out[i] = (byte)(f & 255);
}
return out;
}
}
protected static int toDigit(char ch, int index) throws Exception {
int digit = Character.digit(ch, 16);
if (digit == -1) {
throw new Exception("Illegal hexadecimal character " + ch + " at index " + index);
} else {
return digit;
}
}
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte)((Character.digit(s.charAt(i), 16) << 4) +
Character.digit(s.charAt(i + 1), 16));
}
return data;
}
private IllegalStateException fail(Exception e) {
return new IllegalStateException(e);
}
Decryption
params:
(same as in above java code)
code:
var cipherParams = CryptoJS.lib.CipherParams.create({
ciphertext: CryptoJS.enc.Base64.parse(ciphertext)
});
var decrypted = CryptoJS.AES.decrypt(
cipherParams,
key,
{ iv: CryptoJS.enc.Hex.parse(iv) });
var plaintext = decrypted.toString(CryptoJS.enc.Utf8);

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 ..

Java aes encryption code, how to achieve through nodejs?

Java aes encryption code, how to achieve through nodejs?
I don't know how nodejs should implement the hexStringToBytes function, and aes decrypt
Source code:https://github.com/androider/mahuayingshi-java
public static String decryptHex(String str, String str2) {
str = "6cab6feb4e159bdbcb652ffd544a32db308bb2bd2b00f17c9a3d523c69159a0ed7589f602c30130ad2f0213226281767123cac47ca86c8f24511cec75a89b19227ecbae6b5f4ce564561098f2b12d2d4a6285ed146b0d2217924550c9e10256605077a3a4cff0be84e35627f004708f0";
str2 = "10737929DtXZcHh9";
String decrypt = null;
try {
decrypt = aesDecryptByBytes(hexStringToBytes(str), str2);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(decrypt);
return decrypt;
}
public static byte[] hexStringToBytes(String str) {
int length = str.length() / 2;
byte[] bArr = new byte[length];
for (int i = 0; i < length; i++) {
int i2 = i * 2;
bArr[i] = (byte) (((byte) (hexStr.indexOf(str.charAt(i2)) << 4)) | ((byte) hexStr.indexOf(str.charAt(i2 + 1))));
}
return bArr;
}
private static String aesDecryptByBytes(byte[] bArr, String str) throws Exception {
Cipher instance = Cipher.getInstance("AES/CBC/PKCS7Padding");
byte[] bytes = str.getBytes();
instance.init(2, new SecretKeySpec(bytes, "AES"), new IvParameterSpec(bytes));
return new String(instance.doFinal(bArr));
}

C# equivalent of LZMA-JS compress

I have used some client side javscript code to compress some user input using this javascript library.
In the backend code I have used the code samples from this post to decompress the data server side using C#.
The works perfectly.
Now I would like to be able to compress a string the same way the javascript does. When I compress the code using this sample I get an array of signed integers ranging from -128 to 128. Now I would like to use my backend code to do the same.
The LMZA properties from the javascript are a bit different than the default properties from the C# code but even if I change those to the same values I get different results from the two libraries.
At first the output values from the C# code are unsigned.
Secondly the number of characters returned are different.
The differences may be introduced by the properties of the decoders but I have no idea how to get the two libraries aligned.
My C# uses the LMZA SDK from 7zip
My C# code to decompress the javascript compressed data (comma separated array of signed integers):
public static void Decompress(Stream inStream, Stream outStream)
{
byte[] properties = new byte[5];
inStream.Read(properties, 0, 5);
SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();
decoder.SetDecoderProperties(properties);
long outSize = 0;
for (int i = 0; i < 8; i++)
{
int v = inStream.ReadByte();
outSize |= ((long)(byte)v) << (8 * i);
}
long compressedSize = inStream.Length - inStream.Position;
decoder.Code(inStream, outStream, compressedSize, outSize, null);
}
public static string DecompressLzma(string inputstring)
{
if (!string.IsNullOrEmpty(inputstring))
{
byte[] myInts = Array.ConvertAll(inputstring.Split(','), s => (byte)int.Parse(s));
var stream = new MemoryStream(myInts);
var outputStream = new MemoryStream();
Decompress(stream, outputStream);
using (var reader = new StreamReader(outputStream))
{
outputStream.Position = 0;
string output = reader.ReadToEnd();
return output;
}
}
return "";
}
The code to compress the data is like this (number of bytes are diffrent and unsigned):
public static string CompressLzma(string inputstring)
{
if (!string.IsNullOrEmpty(inputstring))
{
var stream = new MemoryStream(Encoding.Unicode.GetBytes(inputstring ?? ""));
var outputStream = new MemoryStream();
Compress(stream, outputStream);
byte[] bytes = outputStream.ToArray();
}
return "";
}
public static void Compress(MemoryStream inStream, MemoryStream outStream)
{
CoderPropID[] propIDs;
object[] properties;
PrepareEncoder(out propIDs, out properties);
SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();
encoder.SetCoderProperties(propIDs, properties);
encoder.WriteCoderProperties(outStream);
Int64 fileSize = inStream.Length;
for (int i = 0; i < 8; i++)
{
outStream.WriteByte((Byte)(fileSize >> (8 * i)));
}
encoder.Code(inStream, outStream, -1, -1, null);
}
public static void PrepareEncoder(out CoderPropID[] propIDs, out object[] properties)
{
bool eos = true;
Int32 dictionary = 1 << 16;
Int32 posStateBits = 2;
Int32 litContextBits = 3; // for normal files
// UInt32 litContextBits = 0; // for 32-bit data
Int32 litPosBits = 0;
// UInt32 litPosBits = 2; // for 32-bit data
Int32 algorithm = 2;
Int32 numFastBytes = 32;
string mf = "bt2";
propIDs = new CoderPropID[]
{
CoderPropID.DictionarySize,
CoderPropID.PosStateBits,
CoderPropID.LitContextBits,
CoderPropID.LitPosBits,
CoderPropID.Algorithm,
CoderPropID.NumFastBytes,
CoderPropID.MatchFinder,
CoderPropID.EndMarker
};
properties = new object[]
{
dictionary,
posStateBits,
litContextBits,
litPosBits,
algorithm,
numFastBytes,
mf,
eos
};
}
This code works to create the same string the javascript code would, the LMZA settings are included:
public static string CompressLzma(string inputstring)
{
if (!string.IsNullOrEmpty(inputstring))
{
var stream = new MemoryStream(Encoding.UTF8.GetBytes(inputstring ?? ""));
var outputStream = new MemoryStream();
Compress(stream, outputStream);
byte[] bytes = outputStream.ToArray();
var result = string.Join(",", Array.ConvertAll(bytes, v => signedInt((int)v)));
return result;
}
return "";
}
public static void PrepareEncoder(out CoderPropID[] propIDs, out object[] properties)
{
bool eos = true;
Int32 dictionary = 1 << 16;
Int32 posStateBits = 2;
Int32 litContextBits = 3; // for normal files
// UInt32 litContextBits = 0; // for 32-bit data
Int32 litPosBits = 0;
// UInt32 litPosBits = 2; // for 32-bit data
Int32 algorithm = 2;
Int32 numFastBytes = 64;
string mf = "bt4";
propIDs = new CoderPropID[]
{
CoderPropID.DictionarySize,
CoderPropID.PosStateBits,
CoderPropID.LitContextBits,
CoderPropID.LitPosBits,
CoderPropID.Algorithm,
CoderPropID.NumFastBytes,
CoderPropID.MatchFinder,
CoderPropID.EndMarker
};
properties = new object[]
{
dictionary,
posStateBits,
litContextBits,
litPosBits,
algorithm,
numFastBytes,
mf,
eos
};
}
private static int signedInt(int unsignedInt)
{
return unsignedInt >= 128 ? Math.Abs(128 - unsignedInt) - 128 : unsignedInt;
}
public static void Compress(MemoryStream inStream, MemoryStream outStream)
{
CoderPropID[] propIDs;
object[] properties;
PrepareEncoder(out propIDs, out properties);
SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();
encoder.SetCoderProperties(propIDs, properties);
encoder.WriteCoderProperties(outStream);
Int64 fileSize = inStream.Length;
for (int i = 0; i < 8; i++)
{
outStream.WriteByte((Byte)(fileSize >> (8 * i)));
}
encoder.Code(inStream, outStream, -1, -1, null);
}

Categories