I want to encrypt and decrypt "ABCD1234" in AES but the output is not the same.
What I have to do to get the same results?
encrypt in crypto-js
function encrypt(string) {
const key = CryptoJS.enc.Utf8.parse("g#eNR#2H'9n/ZF8s");
const encrypted = CryptoJS.AES.encrypt(string, key, {
iv: CryptoJS.enc.Utf8.parse("Fa6Fy$F8.qRvHKU+"),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.NoPadding
});
return encrypted.toString()
}
document.getElementById("encrypted").innerHTML = encrypt("ABCD1234");
then the output is sRdk5O4U+WA=
when i try to decrypt in java
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
class Main {
public static void main(String[] args) {
String data = "sRdk5O4U+WA=";
String key = "g#eNR#2H'9n/ZF8s";
String iv = "Fa6Fy$F8.qRvHKU+";
try
{
byte[] encrypted1 = Base64.getDecoder().decode(data);
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes("UTF-8"));
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
byte[] original = cipher.doFinal(encrypted1);
String decrypt = new String(original).trim();
System.out.println("decrypt "+decrypt);
} catch (Exception e)
{
System.out.println("e "+e.toString());
}
}
}
throws an exception javax.crypto.IllegalBlockSizeException: Input length not multiple of 16 bytes
java code: https://repl.it/repls/NoxiousWavyMp3
javascript code: https://codepen.io/anon/pen/ydEpZB
Related
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!
I want to encrypt the password before to submit.
app.js
function encryptPass() {
var encrypted = CryptoJS.AES.encrypt("Test", "1234").toString();
$("#password").val(encrypted)
}
After to submit, the tool call method: decrypt
pass.java
public static String decrypt(String strToDecrypt) {
def result
try {
if (strToDecrypt) {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, obtenerSecretKey());
result = new String(cipher.doFinal(Base64.decodeBase64(strToDecrypt)))
}
} catch (Exception e) {
println e
throw e;
} finally {
return result
}
}
private static SecretKeySpec obtenerSecretKey () {
MessageDigest sha = MessageDigest.getInstance("SHA-1");
def semilla = "1234"
def key = sha.digest(semilla.getBytes("UTF-8"));
key = Arrays.copyOf(key, 16);
return new SecretKeySpec(key, "AES");
}
I'm getting this error:
javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
Any suggestions or other encrypt type?
I am encrypting value using CryptoJS in front end but when I tried to decrypt in java am not able to do so.Is there any to decrypt value in java which am getting from front end using cryptojs.
Any help would be greatly appreciated
encryption code:
value="1234"
key="abcdabcd12341234"
encryption(value , key){
var enc4 = CryptoJS.AES.encrypt(value,key);
console.log(enc4.toString());
decryption code:
public static String decryption(String value, String key) throws Exception {
try {
SecretKeySpec secu = new SecretKeySpec(key.getBytes(character),Algorithm);
String value1 = value.trim();
byte[] raw = StringToBytes(value1);
System.out.println(raw);
Cipher cipher = Cipher.getInstance(Algorithm);
cipher.init(Cipher.DECRYPT_MODE, secu);
System.out.println("}}}}}}}}}}}}}}");
byte[] fina = cipher.doFinal(raw);
String g = new String(fina,character);
return g;
}
catch(Exception e) {
System.out.println("dead");
}
return "";
}
public static byte[] StringToBytes(String value1) {
try {
String[] strs = value1.split("");
System.out.println(strs.toString());
byte[] bytes = new byte[strs.length];
System.out.println(bytes);
for(int i=0;i<bytes.length; i++) {
System.out.println("came to for loop");
//bytes[i] = (byte) Integer.parseInt(strs[i]);
//int s = Integer.parseInt(strs[i]);
//System.out.println("ududfdheifdei" + s);
bytes[i]=(byte) Integer.parseInt(strs[i]);
System.out.println("printing decrypted value"+ bytes[i]);
}
return bytes;
}
catch(Exception e) {
System.out.println("long dead");
}
return new byte[0];
}
Looking at your code and reading a bit about cryptojs, I assume you are encrypting in AES/ECB/PKCS5Padding so adding the same tag to your decrypt in java should be enough:
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
You can also take a look at this tutorial and this one that should provide some insight in your problem.
Also, you can take a look at this answer to check how to improve your code. It looks like you could just have:
public static String decryption(String value, String key) throws Exception {
try {
SecretKeySpec secu = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8),"AES");
byte[] raw = value.trim().getBytes(StandardCharsets.UTF_8);
System.out.println(raw);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secu);
System.out.println("}}}}}}}}}}}}}}");
byte[] fina = cipher.doFinal(raw);
return new String(fina,StandardCharsets.UTF_8);
}
catch(Exception e) {
System.out.println("dead");
}
return "";
}
And remove the StringToBytes(String value1).
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!
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])