Different behaviors from Decryption method in java - javascript

i am using decryption alogirthm RSA with public and private keys from certification .
var encrypt = new JSEncrypt();
var publicKey = "example";
encrypt.setPublicKey(publicKey);
var data = encrypt.encrypt(value);
console.log(data);
return data;
public static String getDecrypted(String data, String Key)
throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException,
IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
Cipher cipher = Cipher.getInstance("RSA");
PrivateKey pk = KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(Base64.decodeBase64(Key.getBytes())));
cipher.init(Cipher.DECRYPT_MODE, pk);
// byte[] encryptedbytes =
// cipher.doFinal(Base64.encodeBase64(data.getBytes()));
return new String(cipher.doFinal(Base64.decodeBase64(data)));
}
i am using front end encryption and in main method encryption . the encrypted values from two sides are getting correctly . but when i call it from web
i get another values like that
EAQ�žÃqÈ›#Á¢éz¡?�4zsHD-U€�
KÉ¢a`Õ³=jö`›=šúFhU;••˜ü®2¿¶žñÛ¤lÉê×)§?]¾–`n_üÙ&1ï)ðeÈž‹x¯ø¬#;ýp& Ê*í~ý¾´çVõF¯±ë©yṉ̃©w_f'úH⬒#™G™|¦ý¹j"Ìç8=ŽRÉž[££4™s#àâ
and the value at the end

Related

JAVA encrypted AES 256 CBC To NODE.JS - Problems to migrate code

I have been reading several similar questions and based on that for my initial code. Unfortunately, I still can't get it to work.
key="fb52042ada308dd1d4dfd8a3870d5ab5"
iv = "bb8e0b158f57f63dfeea86e24af1abfc"
data = {"MerchantId":"0000000000000001"}
Get SHA256 from "data" (dataSha256)
Get encryption from Encrypt dataSha256 + iv + key
Result of Hexa encryption, similar to:
fd72fcc16b66d04cf0f4dd2265a59eb675103482bae806b405bb85595056f5770b3202b42d42a87b767892591a333eb6b5c9ad3ef34f4d415f8d3bbc3d0f389e2e5b6f7cd915520c7b2c19225680728b
When migrating the code from Java to Node.js, I don't get similar result. The first problem is that the "iv" should be 16 bytes, however in the code it is 32.
JAVA EXTRACT (original)
public class AesEncryption implements SymmetricEncryptionComponent {
Map<String, String> initParams;
String key, iv;
String mode, encoding;
String keyFile;
String ENCODING = "ISO-8859-1";
public AesEncryption() {
Security.addProvider(new BouncyCastleProvider());
}
// PARAMETERS INITIALITATION
public void setInitParams()
{
initParams=params;
key=” 1ea9a91b0ba908b44f598d2822499441”;
iv= "f20946931dd6e8594dc6f469b5e583ab";
mode= "AES/CBC/PKCS7Padding";
encoding= "HEX";
if(encoding.equalsIgnoreCase("BASE64")&&encoding.equalsIgnoreCase("HEX"))
throw new IllegalArgumentException("AES.ENCODING can only be 'HEX' of 'BASE64'")
}
// INFORMATION CIPHERING return encodeBase24
public String encrypt(String data) {
byte[] output = null;
try {
byte[] keyBytes = decode(key);
byte[] input = data.getBytes(ENCODING);
AlgorithmParameterSpec ivSpec = new
IvParameterSpec(Hex.decodeHex(iv.toCharArray()));
SecretKeySpec keySpec = null;
keySpec = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance(mode);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
output = cipher.doFinal(input);
} catch (Exception e) {
throw new EncryptionException("Error", e);
}
return encode(output);
}
// INFORMATION ENCODE
private String encode(byte[] output) {
if (mode.equalsIgnoreCase("BASE64"))
return Base64.encodeBase64String(output);
else
return new String(Hex.encodeHex(output));
}
// INFORMATION DECODE
private byte[] decode(String data) throws DecoderException {
if (data.indexOf("=") > 0 || data.indexOf("+") > 0)
return Base64.decodeBase64(data);
else
return Hex.decodeHex(data.toCharArray());
}
}
NODE EXTRACT (using crypto-js)
const cryptojs = require("crypto-js");
const crypto = require("crypto");
let jsonData = {"MerchantId":"0000000000000001"};
let key = 'fb52042ada308dd1d4dfd8a3870d5ab5';
let iv = 'bb8e0b158f57f63dfeea86e24af1abfc';
const jsonDataSha256 =
crypto.createHash('sha256').update(JSON.stringify(jsonData)).digest('hex');
key = cryptojs.enc.Latin1.parse(key); //Convierte hex string -> word array
iv = cryptojs.enc.Latin1.parse(iv);
jsonDataSha256Bin = cryptojs.enc.Latin1.parse(jsonDataSha256); //Convert hex
string -> word array
console.log(key);
console.log(iv);
console.log(jsonDataSha256);
let encrypted = cryptojs.AES.encrypt(jsonDataSha256Bin, key, {
iv: iv,
mode: cryptojs.mode.CBC,
padding: cryptojs.pad.Pkcs7,
});
encrypted = encrypted.toString();
const salida = crypto.createHash('sha256').update(encrypted).digest('hex');
console.log(`${salida}`);
//Equals to ce994c4d2b1f398ff0bed22c4b48e1f2170dbf26baf2eaacec96ea6b31667cd6
//No match to Java output.
What will I be doing wrong? Any help is appreciated!

How do i get RSACryptoServiceProvider to verify a message using public key and signature

I generated a private and public key in javascript like this.
import crypto from "crypto";
/*export const { publicKey, privateKey } = crypto.generateKeyPairSync("rsa", {
modulusLength: 2048,
});*/
const pair = crypto.generateKeyPairSync("rsa", { modulusLength: 2048 });
export const privateKey = pair.privateKey.export({
type: "pkcs1",
format: "pem",
});
export const publicKey = pair.publicKey.export({
type: "pkcs1",
format: "pem",
});
Then i use the private key to create a signature for a jsonfile like this, and the public key to verify it before i return the signature.
//Lav signatur
const signate = crypto.createSign("SHA384");
signate.update(Buffer.from(licenseRelationship, "utf-8"));
const signature = signate.sign(privateKey, "hex");
const verifier = crypto.createVerify("SHA384");
// verificer signature, besked
verifier.update(Buffer.from(licenseRelationship, "utf-8"));
const verificationResult = verifier.verify(publicKey, signature, "hex");
This works perfectly, and then i return the json and the signature as a http response.
I recieve it in c# code and store the two components so im can use them later on request.
Upon request i fetch the two components and want to use the signature to check if the json has been tampered with.
I also has the public key in this code.
I do it like this.
string licenseRelationshipJson = licenseRelationshipDAO.getLicenseRelationshipWithoutSignatureAsJson(licenseRelationship);
byte[] signature = Encoding.UTF8.GetBytes(licenseRelationship.signature);
byte[] licenseRelationshipJsonAsArray = Encoding.UTF8.GetBytes(licenseRelationshipJson);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048);
result = rsa.VerifyData(licenseRelationshipJsonAsArray, signature,
HashAlgorithmName.SHA384, RSASignaturePadding.Pkcs1);
if (result)
{
log.write("Message verified ", null);
} else
{
log.write("Message not Verified ", null);
}
All debug code and exception handling removed.
I'm a crypto virgin, and am trying to understand this. But i must have misunderstood something serious.
I have the public key as a string (not base64 encoded)
Ive checked the json, and it is the exact same bytes when signed in Javascript as when being verified in c#
The public key is not used in this process. That has to be wrong i think ?
How do i get the public key into the RWACryptoServiceProvider ?
Im sure im using RWACryptoServiceProvider wrong.
EDIT....:
Ive tried this instead, but still to no avail.
string licenseRelationshipJson = licenseRelationshipDAO.getLicenseRelationshipWithoutSignatureAsJson(licenseRelationship);
byte[] signature = Encoding.UTF8.GetBytes(licenseRelationship.signature);
byte[] licenseRelationshipJsonAsArray = Encoding.UTF8.GetBytes(licenseRelationshipJson);
byte[] asBytes = Encoding.ASCII.GetBytes(DataStorage.Instance.PUBLIC_KEY);
char[] publicKeyAsArray = Encoding.ASCII.GetChars(asBytes);
ReadOnlySpan<char> publicKeyChars = publicKeyAsArray;
RSA rsa = RSA.Create();
try
{
rsa.ImportFromPem(publicKeyChars);
result = rsa.VerifyData(licenseRelationshipJsonAsArray, signature, HashAlgorithmName.SHA384, RSASignaturePadding.Pkcs1);
} catch (CryptographicException cex)
{
log.write("Something went wrong with the crypto verification process", cex);
}
.
.
.
Thankyou for your time.

AES encryption method in NodeJS similar to C sharp function

I have a function written in C#. Basically the function is used to generate a token on the basis of parameters like text and key.
public string Encrypt(string input, string key) {
byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);
byte[] toEncrptArray = UTF8Encoding.UTF8.GetBytes(input);
Aes kgen = Aes.Create("AES");
kgen.Mode = CipherMode.ECB;
kgen.Key = keyArray;
ICryptoTransform cTransform = kgen.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncrptArray, 0, toEncrptArray.Length);
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
I'm trying to search any same alternative for the above function in NodeJS or run this function inside the NodeJS script through any compiler.
I have tried the crypto-js module in NodeJS but got a different token string. Please suggest the alternative function or any idea about running this function inside the NodeJS script.
My Recent code in NodeJS :
First Method :
var CryptoJS = require("crypto-js");
// Encrypt
var ciphertext = CryptoJS.AES.encrypt("<input>", "<key>").toString();
Second Method :
var crypto = require('crypto'),
algorithm = 'aes-256-ctr',
password = '<key>';
function encrypt(text){
var cipher = crypto.createCipher(algorithm,password)
var crypted = cipher.update(text,'utf8','hex')
crypted += cipher.final('hex');
return crypted;
}
Both the method is giving different token if compared to C# function.
The AES algorithm used in the C# code is AES 128-bit in ECB mode.
We can perform the same encryption in Node.js (and decrypt as well if we wish), using the following code:
Node.js Code
const crypto = require("crypto");
function encrypt(plainText, key, outputEncoding = "base64") {
const cipher = crypto.createCipheriv("aes-128-ecb", key, null);
let encrypted = cipher.update(plainText, 'utf8', outputEncoding)
encrypted += cipher.final(outputEncoding);
return encrypted;
}
function decrypt(cipherText, key, outputEncoding = "utf8") {
const cipher = crypto.createDecipheriv("aes-128-ecb", key, null);
let encrypted = cipher.update(cipherText)
encrypted += cipher.final(outputEncoding);
return encrypted;
}
const KEY = Buffer.from("abcdefghijklmnop", "utf8");
console.log("Key length (bits):", KEY.length * 8);
const encrypted = encrypt("hello world", KEY, "base64");
console.log("Encrypted string (base64):", encrypted);
// And if we wish to decrypt as well:
const decrypted = decrypt(Buffer.from(encrypted, "base64"), KEY, "utf8")
console.log("Decrypted string:", decrypted);
C# Code
using System;
using System.Text;
using System.Security.Cryptography;
public class Program
{
public static void Main()
{
Console.WriteLine("Result: " + Encrypt("hello world", "abcdefghijklmnop"));
}
public static string Encrypt(string input, string key) {
byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);
byte[] toEncrptArray = UTF8Encoding.UTF8.GetBytes(input);
Aes kgen = Aes.Create("AES");
kgen.Mode = CipherMode.ECB;
kgen.Key = keyArray;
ICryptoTransform cTransform = kgen.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncrptArray, 0, toEncrptArray.Length);
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
}
The results for the encryption (with plaintext and key as above) are:
.Net: f7sSBDV0N6MOpRJLpSJL0w==
Node.js: f7sSBDV0N6MOpRJLpSJL0w==
Obviously we must not use this key in production!

encryptAES from Java to node.js

I have a Java algorithm for AES encryption and decryption and have to realize the decryption in JavaScript.
public static final String ENCRYPTION_ALGORITHM = "AES/CBC/PKCS5Padding";
public static String wrap(String clearText, String key) {
byte[] iv = getIv();
byte[] cipherText = encrypt(clearText, key, iv);
byte[] wrapped = new byte[iv.length + cipherText.length];
System.arraycopy(iv, 0, wrapped, 0, iv.length);
System.arraycopy(cipherText, 0, wrapped, 16, cipherText.length);
return new String(Base64.encodeBase64(wrapped));
}
private static byte[] encrypt(String clearText, String key, byte[] iv) {
try {
Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM);
AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
params.init(new IvParameterSpec(iv));
cipher.init(Cipher.ENCRYPT_MODE, getKey(key), params);
return cipher.doFinal(clearText.getBytes());
} catch (GeneralSecurityException e) {
throw new RuntimeException("Failed to encrypt.", e);
}
}
private static SecretKeySpec getKey(String key) {
try {
return new SecretKeySpec(Hex.decodeHex(key.toCharArray()), "AES");
} catch (DecoderException e) {
throw new RuntimeException("Failed to generate a secret key spec", e);
}
}
private static byte[] getIv() {
byte[] iv = new byte[16];
new SecureRandom().nextBytes(iv);
return iv;
}
I have wrote javascript code but it generate incorrect result:
var responseBody = JSON.stringify({"key":"215467ryhfdjeu8373t4"});
var initializationVector = crypto.randomBytes(16);
key = new Buffer(key.substring(0,32), 'hex');
var cipher = crypto.createCipheriv('aes-128-cbc', key, iv);
var encrypted = cipher.update(new Buffer(responseBody)) + cipher.final('hex');
var encoded = new Buffer(initializationVector+encrypted, 'binary');
return encoded;
Could you please help me to rewrite Java wrap function to javascript(NodeJS)?
Problem is fixed.
The problem was in concatenate of the buffers. The operator "+" not correct for this. Need use the default method.
Buffer.concat([initializationVector, encrypted])

create C# 256 bit AES encryption like cryptoJS

im trying to encrpyt a payload in c#.
i have the code in Javascript and im trying to create same encryption in C#, having hard time to recreate the same encryption.
given javascript code (cannot be changed):
var data =
{
'username':username,
'password':password,
'isPersistent':'false'
};
var encrypted = CryptoJS.AES.encrypt(JSON.stringify(data),token, { format: JsonFormatter });
var body = {
payload: JSON.parse(encrypted.toString()),
token: token
}
debugger
$.post(url, body).success(resultFunction)
i want to create the same encryption in c#
Dictionary<string, string> data = new Dictionary<string, string>();
data.Add("username", username);
data.Add("password", password);
data.Add("isPersistent", "false");
string token = "7e4bac048ef766e83f0ec8c079e1f90c2eb690a9";
string serializedData = json_serialize(data);
string encrypted = EncryptText(serializedData, token);
Dictionary<string, string> body = new Dictionary<string, string>();
body.Add("payload", json_deserialize(encrypted));
body.Add("token", token);
var loginWebRequest = createWebRequest(address, "POST", json_serialize(body));
i have several issue here, in js you can specify the format of encryption and then use JSON.parse.
it seems it cannot be done in c#.
i used the methods from http://www.codeproject.com/Articles/769741/Csharp-AES-bits-Encryption-Library-with-Salt.
is there anyway i can create the same code snippet in c#?
Thanks!
The code from this post: openssl using only .NET classes is compatible with CryptoJS AES.
Test:
JS:
var encrypted = CryptoJS.AES.encrypt("abc12345","7e4bac048ef766e83f0ec8c079e1f90c2eb690a9");
encrypted.toString(); //output: "U2FsdGVkX18eGD2hSe9UyGgTk5NGKFmvWq/3c5IYHoQ="
C#:
var p = new Protection();
var s = p.OpenSSLDecrypt("U2FsdGVkX18eGD2hSe9UyGgTk5NGKFmvWq/3c5IYHoQ=", "7e4bac048ef766e83f0ec8c079e1f90c2eb690a9");
Console.WriteLine(s);//output: "abc12345"

Categories

Resources