TripleDES encrypt and decrypt in javascript - CryptoJS - javascript

I'm using CryptoJS library to TripleDES function but the decrypt data doesn't work. my decrypted data dons't return the origin string.
var t = "a";
var d = "john";
var key = CryptoJS.MD5(t).toString()
var param = CryptoJS.TripleDES.encrypt(d, key).toString();
console.log('decrypt',CryptoJS.TripleDES.decrypt(param, key).toString())
console.log('encrypt',param) // it should return `john`. but it returns a different value.
the result of this encryption:
decrypt 6a6f686e
encrypt U2FsdGVkX19Ww0uMTSo+qAV5PVzsEhSR
https://github.com/brix/crypto-js

solved:
You should CryptoJS.enc.Utf8 inside toString function.
console.log('decrypt',CryptoJS.TripleDES.decrypt(param, key).toString(CryptoJS.enc.Utf8))

Related

Encrypting With CryptoJS

I am trying to use the CryptoJS library to get the same value as I'm getting from an encryption tool, but I'm not able to get the same encrypted value.
Result using encryption tool:
Base64 Encoded Key: SisBCd6mVzPzZP7cpl/HvjqdkCpnujnJKUu8iosq/Yc=
Value to Encrypt: 55554444
Encrypted (ECB) Base64 Encoded Value: MLnK8JOyp+J4CoaqcWTAnW==
Here is my code where I'm trying to get that same result:
var data = '55554444'
var key = 'SisBCd6mVzPzZP7cpl/HvjqdkCpnujnJKUu8iosq/Yc='
// encrypt with key
var encrypted_ecb = CryptoJS.AES.encrypt(data, key, {mode: CryptoJS.mode.ECB});
console.log('encrypted_ecb: ', encrypted_ecb.toString())
// to base64
var rawStr = encrypted_ecb;
var wordArray = CryptoJS.enc.Utf8.parse(rawStr);
var base64_ecb = CryptoJS.enc.Base64.stringify(wordArray);
console.log('encrypted_base64_ecb: ', base64_ecb);
// Console Result:
// encrypted_ecb: U2FsdGVkX196PQg/s6RPQr3V9GEjf/WP7qRXxVh5GEU=
// encrypted_base64_ecb: VTJGc2RHVmtYMTk2UFFnL3M2UlBRcjNWOUdFamYvV1A3cVJYeFZoNUdFVT0=
As you can see I am getting the result I get is far different than the result I'm getting with the tool. Can anyone point me in the right direction?
Thank you!
You'll need to parse the key as well. Change the following line
var key = 'SisBCd6mVzPzZP7cpl/HvjqdkCpnujnJKUu8iosq/Yc='
to
var key = CryptoJS.enc.Base64.parse('SisBCd6mVzPzZP7cpl/HvjqdkCpnujnJKUu8iosq/Yc=');

Encrypting data with forgejs on the client side, and decrypting with ruby

For a given project, I'm looking to encrypt a piece of data with AES 256, and then RSA encrypt the key. I've been using Forge and the Encryptor gem in ruby, and i can't seem get matching encryption values:
var key = 'strengthstrengthstrengthstrength';
var iv = 'cakecakecakecakecakecakecakecake';
var cipher = forge.aes.createEncryptionCipher(key, 'CBC');
cipher.start(iv);
cipher.update(forge.util.createBuffer("some string"));
cipher.finish();
var encrypted = cipher.output;
console.log(btoa(encrypted.data)); // outputs: CjLmWObDO2Dlwa5tJnRBRw==
Then in IRB:
Encryptor.encrypt 'some string', :key => 'strengthstrengthstrengthstrength', :key => 'cakecakecakecakecakecakecakecake'
Base64.encode64 _
# outputs: C9Gtk9YfciVMJEsbhZrQTw==\n
Over using string values for Key & IV, tried:
var key = forge.random.getBytesSync(32);
var iv = forge.random.getBytesSync(32);
Then doing a btoa() call on each of them. Using the Base64.decode64 on the ruby side, before passing them to Encryptor.decrypt, but still no luck.
Any idea where i've gone wrong?
I managed to get it to work. Since i'm just using one key to encrypt one value, i just used the key as the IV & Salt as well. This is not recommended if you are using the key to encrypt multiple values. You will then need to generate proper salt & iv values.
Also the gen key value is a pretty poor way, as Math.random is not secure. Just ran out of time to do this properly, but works okay for this case.
var Encryption = (function () {
var api = {
getKey: function () {
var possible = "ABCDEFabcdef0123456789";
var key = '';
for (var i = 0; i < 32; i++) {
key += possible.charAt(Math.floor(Math.random() * possible.length));
}
return key;
},
encryptPII: function (rawKey, value) {
var salt = rawKey;
var iv = rawKey;
var key = forge.pkcs5.pbkdf2(rawKey, salt, 2000, 32);
var cipher = forge.aes.createEncryptionCipher(key, 'CBC');
cipher.start(iv);
cipher.update(forge.util.createBuffer(value));
cipher.finish();
return btoa(cipher.output.data);
}
};
return api;
})();
The rawKey is the value returned from getKey(). The value property is the the string to be encrypted. I use the rawkey for iv & salt values, generate a key in the same way that the Encryptor gem in ruby does. Use forge to then encrypt the string value.
If i take the base64, decode it in ruby, and pass the same rawKey value to the encryptor gem for key, salt and iv, it works.

Encrypt text using AES in Javascript then Decrypt in C# WCF Service

I am trying to Encrypt a string using AES 128bit encryption. I have code for both Javascript and C#. The main objective is to encrypt the string using Javascript CryptoJS and then take the resultant cipher text and Decrypt it using C# AES AesCryptoServiceProvider.
Javascript Code:
function EncryptText()
{
var text = document.getElementById('textbox').value;
var Key = CryptoJS.enc.Hex.parse("PSVJQRk9QTEpNVU1DWUZCRVFGV1VVT0=");
var IV = CryptoJS.enc.Hex.parse("YWlFLVEZZUFNaWl=");
var encryptedText = CryptoJS.AES.encrypt(text, Key, {iv: IV, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7});
//var decrypted = CryptoJS.AES.decrypt(encrypted, "Secret Passphrase");
var encrypted = document.getElementById('encrypted');
encrypted.value = encryptedText;
}
C# Code:
private String AES_decrypt(string encrypted)
{
byte[] encryptedBytes = Convert.FromBase64String(encrypted);
AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
aes.BlockSize = 128;
aes.KeySize = 256;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.Pkcs7;
aes.Key = Key;
aes.IV = IV;
ICryptoTransform crypto = aes.CreateDecryptor(aes.Key, aes.IV);
byte[] secret = crypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
crypto.Dispose();
return System.Text.ASCIIEncoding.ASCII.GetString(secret);
}
When using "hello" as the plain text for javascript i get this ciphertext:
uqhe5ya+mISuK4uc1WxxeQ==
When passing that into the C# application, upon running the Decrypt method i recieve:
Padding is invalid and cannot be removed.
I am stumped here and have tried many solutions resulting in the same error.
When encrypting hello through the C# encryption AES method I receive:
Y9nb8DrV73+rmmYRUcJiOg==
I thank you for your help in advance!
javascript code :
function EncryptText()
{
var text = CryptoJS.enc.Utf8.parse(document.getElementById('textbox').value);
var Key = CryptoJS.enc.Utf8.parse("PSVJQRk9QTEpNVU1DWUZCRVFGV1VVT0="); //secret key
var IV = CryptoJS.enc.Utf8.parse("2314345645678765"); //16 digit
var encryptedText = CryptoJS.AES.encrypt(text, Key, {keySize: 128 / 8,iv: IV, mode: CryptoJS.mode.CBC, padding:CryptoJS.pad.Pkcs7});
var encrypted = document.getElementById('encrypted');
encrypted.value = encryptedText;
//Pass encryptedText through service
}
C# code :
private String AES_decrypt(string encrypted,String secretKey,String initVec)
{
byte[] encryptedBytes = Convert.FromBase64String(encrypted);
AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
//aes.BlockSize = 128; Not Required
//aes.KeySize = 256; Not Required
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.Pkcs7;
aes.Key = Encoding.UTF8.GetBytes(secretKey);PSVJQRk9QTEpNVU1DWUZCRVFGV1VVT0=
aes.IV = Encoding.UTF8.GetBytes(initVec); //2314345645678765
ICryptoTransform crypto = aes.CreateDecryptor(aes.Key, aes.IV);
byte[] secret = crypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
crypto.Dispose();
return System.Text.ASCIIEncoding.ASCII.GetString(secret);
}
Used above code working fine !!!
Try using var Key = CryptoJS.enc.Utf8.parse("PSVJQRk9QTEpNVU1DWUZCRVFGV1VVT0="); instead of HEX.
Because actually the string you are putting in your key (and IV) and parsing is not a hex string. hex is 0 to F.
First, your Key variable in JS contains a string with 32 characters (after the odd-looking parse call). Although this might be interpreted as a 128-bit key, there is a certain chance that CryptoJS takes it as a pass phrase instead (and generates a key from it using some algorithm). So your actual key looks quite different. The string also looks suspiciously like hex-encoded, so there might be some additional confusion about its C# value. You have to make sure that you are using the same key in JS and C#.
Second, the IV variable also, after parsing, looks like a hex-encoded value. So you have to be careful what value you are using on the C# side as well.
FYI, here are the values for Key and IV after parsing:
Key = 00000000000e00000d000c0000010000,
IV = 0000000e000f0a00
Thank you "Uwe" parsing with UTF8 solved everything.
What happens if you use: var Key = CryptoJS.enc.Utf8.parse("PSVJQRk9QTEpNVU1DWUZCRVFGV1VVT0="); instead >of HEX? And what is your Key and IV in C#? Because actually the string you are putting in your key and >parsing is not a hex string. hex is 0 to F
Thank you so much!

reading encrypted object in javascript

var token = "WMwiDeJrawUKHif7D5a8yd4ne6Mv";
var salt = "ERtrg56hfg5";
var key = CryptoJS.enc.Hex.parse('B374A26A71490437AA024E4FADD5B497FDFF1A8EA6FF12F6FB65AF2720B59CCF');
var iv = CryptoJS.enc.Hex.parse('7E892875A52C59A3B588306B13C31FBD');
var encrypted = CryptoJS.AES.encrypt(token, key, { iv: iv });
context.setVariable("encryptedtoken", encrypted);
but it is not setting to variable saying it is an object.
what I need to do
I think you have to use encrypted.ciphertext
var encrypted = CryptoJS.AES.encrypt(token, key, { iv: iv });
context.setVariable("encryptedtoken", encrypted.ciphertext);
From CryptoJS documentation:
The ciphertext you get back after encryption isn't a string yet. It's a CipherParams object. A CipherParams object gives you access to all the parameters used during encryption. When you use a CipherParams object in a string context, it's automatically converted to a string according to a format strategy. The default is an OpenSSL-compatible format.
<script>
var encrypted = CryptoJS.AES.encrypt("Message", "Secret Passphrase");
alert(encrypted.key); // 74eb593087a982e2a6f5dded54ecd96d1fd0f3d44a58728cdcd40c55227522223
alert(encrypted.iv); // 7781157e2629b094f0e3dd48c4d786115
alert(encrypted.salt); // 7a25f9132ec6a8b34
alert(encrypted.ciphertext); // 73e54154a15d1beeb509d9e12f1e462a0
alert(encrypted); // U2FsdGVkX1+iX5Ey7GqLND5UFUoV0b7rUJ2eEvHkYqA=
</script>

combined RC4 RSA encrypt/decrypt for long messages Javascript

NOTE: Yes, I understand there is a lot of code in this message, but you do encourage us to show prior research and how we've been trying.
Let me preface this by saying, I am not interested in the security of this function. All I want is to encrypt and decrypt arbitrarily long messages using RSA. Usually to do this, the message is encrypted using a block cipher (such as AES) and encrypting the key with the RSA cipher. However, I am just trying to find the easiest way to encrypt/decrypt long messages, irregardless of security. Hence why I am using RC4 in place of the block cipher.
Now, I can encrypt properly using the following code:
function encryptLong(signedCert, msg) {
var key256Bits = CryptoJS.SHA256("password");
var ciphertext = CryptoJS.RC4.encrypt(msg, key256Bits);
key = new RSAKey();
var m = CryptoJS.SHA256("password").toString(CryptoJS.enc.Hex);
m = new BigInteger(m, 16);
key.setPublic(signedCert.msg.subject.pk.n, signedCert.msg.subject.pk.e);
var ctxt = key.doPublic(m).toString(16);
var cipherstring = ciphertext + ":" + ctxt;
var obj = { "type": "CTXT-LONG", "encrypted": cipherstring };
return JSON.stringify(obj);
}
The message and the key are encrypted properly. I tested them individually using these functions.
function encryptRSA(signedCert, msg) {
//create a new RSA key object
var key = new RSAKey();
//convert ASCII message to hex
var m = asciiToHex(msg);
// create new BigInterger from m
m = new BigInteger(m, 16);
// set the values for the public key
key.setPublic(signedCert.msg.subject.pk.n, signedCert.msg.subject.pk.e);
// compute the RSA public key operation, and convert to a hex value
var ctxt = key.doPublic(m).toString(16);
//enter ctxt into the JSON obj
var obj = { "type": "CTXT-SHORT", "c": ctxt };
return JSON.stringify(obj);
}
And...
function encryptRSA(password, message) {
var key256Bits = CryptoJS.SHA256(password);
var ciphertext = CryptoJS.RC4.encrypt(CryptoJS.enc.Utf8.parse(message), key256Bits);
return ciphertext;
}
Now, here is our decryption code:
function decryptLong(sk, ctxt) {
key = new RSAKey();
encryptedStuff = JSON.stringify(ctxt.encrypted);
log(encryptedStuff);
splitEncryptedstuff = encryptedStuff.split(":");
rsaencryption = splitEncryptedstuff[1];
log(rsaencryption);
rc4encryption = splitEncryptedstuff[0];
log(rc4encryption);
c = new BigInteger(rsaencryption, 16);
key.setPrivate(sk.n, sk.e, sk.d);
var key256Bits = key.doPrivate(c).toString(16);
log(key256Bits);
// RC4 decryption
var message = CryptoJS.RC4.decrypt(rc4encryption, key224Bits);
// var ptxt = CryptoJS.enc.Utf8.stringify(message);
// log(ptxt);
return CryptoJS.enc.Utf8.stringify(message);
}
This code doesn't decrypt properly, but I know parts of it work. For example, where I have
log(key356Bits);
it returns the key exactly. So I know that at least the RSA decryption works. What I don't understand is, I followed the decryption function that I have exactly. Which is as follows.
function decryptRC4(password, ciphertext) {
var key256Bits = CryptoJS.SHA256(password);
var message = CryptoJS.RC4.decrypt(ciphertext, key256Bits);
return CryptoJS.enc.Utf8.stringify(message);
}
Well not exactly, I don't have to take the Hash of the password to get the key, as I already have the key. But, I still don't understand what is not working. When we decrypt our ciphertext using this individual function, the plaintext is correct.
Any assistance in this matter would be greatly appreciated.
Knowing my luck, it's probably just something annoying like it's in the wrong encoding type thing.

Categories