How to implement java MessageDigest with CryptoJS - javascript

JAVA CODE:
byte[] n;
byte[] m;
MessageDigest digest = MessageDigest.getInstance("SHA-1");
digest.reset();
digest.update(n);
byte[] hashed = digest.digest(m);
StringBuilder hexValue = new StringBuilder();
for (byte b : hashed) {
int val = ((int) b) & 0xff;
if (val < 16) {
hexValue.append("0");
}
hexValue.append(Integer.toHexString(val));
}
System.out.println(hexValue.toString());
How to implement the above code with CryptoJS ?
Thanks!

The following codeļ¼š
var n; // n="abc"
var m; // m="123"
var sha1 = CryptoJS.algo.SHA1.create();
sha1.update(n);
var hashed = sha1.finalize(m);
console.log(hashed.toString());

Related

How to write the equivalent of this Java encryption function in the Node JS

This is the function used to encrypt in java
public static String encryptionFunction(String fieldValue, String pemFileLocation) {
try {
// Read key from file
String strKeyPEM = "";
BufferedReader br = new BufferedReader(new FileReader(pemFileLocation));
String line;
while ((line = br.readLine()) != null) {
strKeyPEM += line + "\n";
}
br.close();
String publicKeyPEM = strKeyPEM;
System.out.println(publicKeyPEM);
publicKeyPEM = publicKeyPEM.replace("-----BEGIN PUBLIC KEY-----\n", "");
publicKeyPEM = publicKeyPEM.replace("-----END PUBLIC KEY-----", "").replaceAll("\\s", "");;
byte[] encoded = Base64.getDecoder().decode(publicKeyPEM);
// byte[] encoded = Base64.decode(publicKeyPEM);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pubKey = (PublicKey) kf.generatePublic(new X509EncodedKeySpec(encoded));
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] cipherData = cipher.doFinal(fieldValue.getBytes());
if (cipherData == null) {
return null;
}
int len = cipherData.length;
String str = "";
for (int i = 0; i < len; i++) {
if ((cipherData[i] & 0xFF) < 16) {
str = str + "0" + java.lang.Integer.toHexString(cipherData[i] & 0xFF);
} else {
str = str + java.lang.Integer.toHexString(cipherData[i] & 0xFF);
}
}
return str.trim();
} catch (Exception e) {
System.out.println("oops2");
System.out.println(e);
}
return null;
}
I want the equivalent of this in javascript/Nodejs, i tried this:
import * as NodeRSA from 'node-rsa';
private encryptionFunction(fieldValue: string , pemkey: string) : string {
const rsa = new NodeRSA(pemkey);
const encrypted= rsa.encrypt(fieldValue , 'hex')
return encrypted
}
But the output size of both functions is the same, but apparently the encryption type is wrong.
Node-RSA applies OAEP (here) as padding by default, so the PKCS#1 v1.5 padding used in the Java code must be explicitly specified. This has to be added after key import and before encryption:
rsa.setOptions({ encryptionScheme: 'pkcs1' });
Alternatively, the padding can be specified directly during key import:
const rsa = new NodeRSA(pemkey, { encryptionScheme: 'pkcs1' });
With this change, both codes are functionally identical.
Regarding testing: Keep in mind that RSA encryption is not deterministic, i.e. given the same input (key, plaintext), each encryption provides a different ciphertext. Therefore, the ciphertexts of both (functionally identical) codes will be different even if the input is identical. So this is not a bug, but the expected behavior.
How then can the equivalence of both codes be proved? E.g. by decrypting both ciphertexts with the same code/tool.

how to convert this code in javascript to java

i have this code in javascript and i need to convert it to java
but im not expert in javascript.
here the code:
function keyGen(mat)
{
var hash = base64_encode(pack("H*", sha1($mat)));
var l = obj.hash.length - 4;
var p1 = Math.floor(Math.random() * (l+1)) ;
var p2 = Math.floor(Math.random() * (l+1)) ;
var p3 = Math.floor(Math.random() * (l+1)) ;
var motif1 = obj.hash.substr(p1, 4) ;
var motif2 = obj.hash.substr(p2, 4) ;
var motif3 = obj.hash.substr(p3, 4) ;
var cle = motif1+motif2+motif3 ;
return cle ;
}
for the hash i use the function but i can't to modify it:
public static String get_SHA_512_SecurePassword(String passwordToHash, String salt){
String generatedPassword = null;
try {
MessageDigest md = MessageDigest.getInstance("SHA-512");
md.update(salt.getBytes(StandardCharsets.UTF_8));
byte[] bytes = md.digest(passwordToHash.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for(int i=0; i< bytes.length ;i++){
sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
}
generatedPassword = sb.toString();
}
catch (NoSuchAlgorithmException e){
e.printStackTrace();
}
return generatedPassword;
}
function keyGen(mat) {
// seems to get the sha1 of $mat (whatever that is),
// converts this sha1 into HEX string
// encode the hex string into into base64
// the above is a GUESS, as I don't know what library you are using for these functions
var hash = base64_encode(pack("H*", sha1($mat)));
// length of `obj.hash` - whatever that is
var l = obj.hash.length - 4;
// random number between 0 and l + 1
var p1 = Math.floor(Math.random() * (l+1)) ;
// random number between 0 and l + 1
var p2 = Math.floor(Math.random() * (l+1)) ;
// random number between 0 and l + 1
var p3 = Math.floor(Math.random() * (l+1)) ;
// a substring of whatever obj.hash is, from position p1 length 4
var motif1 = obj.hash.substr(p1, 4) ;
// a substring of whatever obj.hash is, from position p2 length 4
var motif2 = obj.hash.substr(p2, 4) ;
// a substring of whatever obj.hash is, from position p3 length 4
var motif3 = obj.hash.substr(p3, 4) ;
// the string concatenation of the above three strings
var cle = motif1+motif2+motif3 ;
// returns this 12 character string
return cle ;
}
Now, all you need to figure out is
What is base64_encode
what is pack
what is sha1
what is $mat
what is obj that you use obj.hash from
why you are creating hash and never using it
why you never use the mat argument
here is the full code : i found it ..... thanks all
public static String get_SHA_512_SecurePassword(String passwordToHash, String salt){
String generatedPassword = null;
try {
MessageDigest md = MessageDigest.getInstance("SHA-512");
md.update(salt.getBytes(StandardCharsets.UTF_8));
byte[] bytes = md.digest(passwordToHash.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for(int i=0; i< bytes.length ;i++){
sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
}
// String base64 = Base64.encodeBase64(sb.toString());
generatedPassword = sb.toString();
}
catch (NoSuchAlgorithmException e){
e.printStackTrace();
}
return generatedPassword;
}
public static String keyGen(String Studentpass,String SaltCrypter) {
String hash=get_SHA_512_SecurePassword(Studentpass,SaltCrypter);
int l = hash.length() - 4;
new Random().nextInt();
int p1 = new Random().nextInt(l) ;
int p2 = new Random().nextInt(l) ;
int p3 = new Random().nextInt(l) ;
String motif1 = hash.substring(p1, p1+4);
String motif2 = hash.substring(p2, p2+4);
String motif3 = hash.substring(p3, p3+4);
String cle =(motif1+motif2+motif3);
cle.replace("l", "L").replace("O", "o").replace("I", "i");
return cle;
}
let arr = [
{url: 'http://172.25.38.138:4000/moservice/create1', startTime: '04/11/2022 16:04:15', endTime: '04/11/2022 16:24:15'},
{url: 'http://172.25.38.138:4000/moservice/create2', startTime: '04/11/2022 16:24:15', endTime: '04/11/2022 16:34:15'},
{url: 'http://172.25.38.138:4000/moservice/create3', startTime: '04/11/2022 16:34:15', endTime: '04/11/2022 16:54:15'},
{url: 'http://172.25.38.138:4000/moservice/create4', startTime: '04/11/2022 17:04:15', endTime: '04/11/2022 17:14:15'}
];
let curntTime = new Date()
function getUrl(arr) {
for (let i = 0; i < arr.length; i++) {
let startTime = new Date(arr[i].startTime)
let endTime = new Date(arr[i].endTime)
if (curntTime > startTime && curntTime < endTime) {
console.log(arr[i].url)
}
}
}
getUrl(arr)
B

How to replicate same Android encrypt method in React-native?

I'm creating a react-native application, where I need to encrypt with TripleDES using ECB mode and Pkcs7 padding.
I have an Android Java piece of code that do the encrypt algorithm i want to replicate.
In react-native I added "CryptoJS" from https://github.com/brix/crypto-js and I called CryptoJS.enc.TripleDES.encrypt() method but it returns a different result than expected.
This is Android code i want to reach:
private static byte[] encrypt(String message, String privateKeyMobile) throws Exception {
final MessageDigest md = MessageDigest.getInstance("MD5");
final byte[] digestOfPassword = md.digest(privateKeyMobile.getBytes("utf-8"));
final byte[] keyBytes = new byte[24];
int q;
for (q = 0; q < 24 && q < digestOfPassword.length; q++) {
keyBytes[q] = digestOfPassword[q];
}
if (q < 24) {
for (int u = q; u < 24; u++)
keyBytes[u] = 0;
}
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
final byte[] plainTextBytes = message.getBytes("utf-8");
return cipher.doFinal(plainTextBytes);
}
This one is my react-native code:
encrypt(message, key) {
let md5key = CryptoJS.enc.MD5(key);
var ciphertext = TripleDES.encrypt(message, md5key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return ciphertext;
}
The two functions returns different outputs.
This php code makes same work as Java code:
https://webtools.workontech.com/triple-des-encryption-online
Other online TripleDES tools return the same react-native result.

SHA512HMAC in node.js does not match C#

I have a simple node.js script
var text = "Hello!";
var serverSeed = "d8818b38a14e7461e87301ad4b9809b558bcbca816b650cd470452e018ada255";
var crypto = require('crypto');
var hash = crypto.createHmac('sha512', serverSeed).update(text).digest('hex');
console.log(hash);
I also have the C# program
using System;
using System.Text;
using System.Security.Cryptography;
public class Program
{
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;
}
public static string ByteArrayToString(byte[] ba)
{
StringBuilder hex = new StringBuilder(ba.Length * 2);
foreach (byte b in ba)
hex.AppendFormat("{0:x2}", b);
return hex.ToString();
}
public static void Main()
{
var serverSeed = StringToByteArray("d8818b38a14e7461e87301ad4b9809b558bcbca816b650cd470452e018ada255");
using (var sha = new HMACSHA512(serverSeed))
{
var hash = sha.ComputeHash(Encoding.ASCII.GetBytes("Hello!"));
Console.WriteLine(ByteArrayToString(hash));
}
}
}
(runable version here)
I get from the node.js program
99e3b20acaa9c7674f074da950945ee897876b0afc02121d5a89fa581081465f3e01a084e9b05bed729b7fbdc1d485fb38af7d6f501cbc258b6c66add54410ba
And from the C# program
73250817a927f394b0912afcece47b8c12aeaed31892c64116ae9dd0d407f6e31d5c062d65f68a3cae09a8acb14a7cef1f6afd99f5a22f2b73e46a991fcd079a
What am I doing wrong to cause this difference?
Your C# code is converting the hex characters in your seed to a byte array based on the what the characters represent in hexadecimal format.
But your node code is passing the seed as a string which is converting the characters to a byte.
So for example, your C# code is converting a to a byte with the value of 10 but your node code would be converting a to a byte with the value of 97
Your node code either needs to convert the hex in your string to a Buffer based on their hex values as you are doing in C#.
var text = "Hello!";
var serverSeed = "d8818b38a14e7461e87301ad4b9809b558bcbca816b650cd470452e018ada255";
var crypto = require('crypto');
var buff = new Buffer(seed, "hex")
var hash = crypto.createHmac('sha512', buff).update(text).digest('hex');
console.log(hash);
Or in C# instead of converting hex to bytes you can get a byte array representing the actually characters the seed using GetBytes from a System.Text.Encoding instance.
var serverSeed = Encoding.ASCII.GetBytes("d8818b38a14e7461e87301ad4b9809b558bcbca816b650cd470452e018ada255");
using (var sha = new HMACSHA512(serverSeed))
{
var hash = sha.ComputeHash(Encoding.ASCII.GetBytes("Hello!"));
Console.WriteLine(ByteArrayToString(hash));
}
Most likely you intended to pass the serverSeed as a buffer in the node.js code.

AES ECB No padding

I am trying to implement AES/ECB/NoPadding with cryptojs.
On the Java side I have this:
public static String encrypt(String input, String key) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
return DatatypeConverter.printHexBinary(cipher.doFinal(padToMultipleOf32(input.getBytes())));
}
public static byte[] padToMultipleOf32(final byte[] bytes) {
int n16 = ((bytes.length + 31) / 32);
int paddedLen = n16 * 32;
byte[] result = new byte[paddedLen];
for (int i = 0; i < bytes.length; i++) {
result[i] = bytes[i];
}
for (int i = bytes.length; i < paddedLen; i++) {
result[i] = 0x00;
}
System.out.println(new String(result).length());
return result;
}
Running Test.encrypt("test", "4g2ef21zmmmhe678")
Gives me: C24F53DDEAD357510A27AA283C74BBF4638B3F81F8EB44652D424D7C32897525
How would I do the same in cryptojs, what I have currently doesnt work:
var pwd = CryptoJS.AES.encrypt("test", "4g2ef21zmmmhe678", {
mode : CryptoJS.mode.ECB,
padding : CryptoJS.pad.NoPadding
});
expect(pwd.ciphertext.toString(CryptoJS.enc.Base64)).toEqual("C24F53DDEAD357510A27AA283C74BBF4638B3F81F8EB44652D424D7C32897525");
Please help
The documentation of CryptoJS says that when passing a plain passphrase (i.e. a String) to encrypt () , it will automatically generate a 256 bit key (Java implements the 128 bit version) using that password as the seed.
To prevent that you can use this function to directly convert your passphrase to a key:
var key = CryptoJS.enc.Utf8.parse("password");
Possibly you will also have to synchronize the encodings of the ciphertexts. See here for a detailed example on how to perform interoperable encryption with Java and CryptoJS.

Categories

Resources