Java and JavaScript hash with SHA-256 difference result - javascript

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.

Related

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

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);

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));
}

How to emulate Javascript crypto AES-256-CBC decipher in Java

I have the following Javascript code in a web page:
var decrypt = function (text, password){
var decipher = crypto.createDecipher('aes-256-cbc',password);
var dec = decipher.update(text,'hex','utf8');
dec += decipher.final('utf8');
return dec;
}
, and I'm trying to reproduce it using Java, using the following:
static MessageDigest MD5 = null;
static {
try {
MD5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
public static String decrypt(String cipherText, String password)
throws GeneralSecurityException, UnsupportedEncodingException {
byte[] passwordBytes = hexStringToByteArray(password);
byte[] keyBytes = MD5.digest(passwordBytes);
byte[] keyAndPassword = new byte[keyBytes.length + passwordBytes.length];
System.arraycopy(keyBytes, 0, keyAndPassword, 0, keyBytes.length);
System.arraycopy(passwordBytes, 0, keyAndPassword, keyBytes.length, passwordBytes.length);
byte[] ivBytes = MD5.digest(keyAndPassword);
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec iv = new IvParameterSpec(ivBytes);
byte[] encrypted = hexStringToByteArray(cipherText);
Cipher aesCBC = Cipher.getInstance("AES/CBC/PKCS5Padding");
aesCBC.init(Cipher.DECRYPT_MODE, key, iv);
byte[] decryptedData = aesCBC.doFinal(encrypted);
return new String(decryptedData, StandardCharsets.UTF_8);
}
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;
}
which pieces bits from:
Encrypt with Node.js Crypto module and decrypt with Java (in Android app)
CryptoJS AES encryption and Java AES decryption
, but I get "javax.crypto.BadPaddingException: Given final block not properly padded", on parameters which the JS function decodes correctly.
Note that Given final block not properly padded does not answer this question- as it is obvious that this is a padding problem but the solution is to replicate whatever the JS crypto lib does, which is not well documented.

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