Hello i'm trying to encrypt and decrypt files (in Uint8Array format) using CryptoJS Library (3.1.2)
This is my code:
var WPAES = {
keySize: 256,
ivSize: 128,
saltSize: 128,
iterations:1000,
encrypt: function(data,passphrase)
{
try
{
var iv = CryptoJS.lib.WordArray.random(this.ivSize/8);
console.log(iv.toString());
var salt = CryptoJS.lib.WordArray.random(this.saltSize/8);
console.log(salt.toString());
var key = CryptoJS.PBKDF2(passphrase, salt, {
keySize: this.keySize/32,
iterations: this.iterations
});
var encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.u8array.parse(data), key, {
iv: iv,
padding: CryptoJS.pad.Pkcs7,
mode: CryptoJS.mode.CBC
});
var encryptedIv = CryptoJS.enc.u8array.stringify(iv);
var encryptedSalt = CryptoJS.enc.u8array.stringify(salt);
var encryptedArray = CryptoJS.enc.u8array.stringify(encrypted.ciphertext);
var message = new Uint8Array(encryptedIv.length + encryptedSalt.length + encryptedArray.length);
message.set(encryptedIv);
message.set(encryptedSalt, encryptedIv.length);
message.set(encryptedArray, encryptedIv.length+encryptedSalt.length);
return message;
}
catch(e)
{
console.log(e);
return false;
}
},
decrypt: function(data,passphrase)
{
try
{
var iv = CryptoJS.enc.u8array.parse(data.slice(0, this.ivSize/8));
console.log(iv.toString());
var salt = CryptoJS.enc.u8array.parse(data.slice(this.ivSize/8, this.ivSize/8+this.saltSize/8))
console.log(salt.toString());
var encrypted = CryptoJS.enc.u8array.parse(data.slice(this.ivSize/8+this.saltSize/8));
var key = CryptoJS.PBKDF2(passphrase, salt, {
keySize: this.keySize/32,
iterations: this.iterations
});
var decrypted = CryptoJS.AES.decrypt(encrypted, key, {
iv: iv,
padding: CryptoJS.pad.Pkcs7,
mode: CryptoJS.mode.CBC
});
var res = CryptoJS.enc.u8array.stringify(decrypted.ciphertext);
return res;
}
catch(e)
{
console.log(e);
return false;
}
}
}
I'm also use:
CryptoJS.enc.u8array = {
stringify: function (wordArray) {
var words = wordArray.words;
var sigBytes = wordArray.sigBytes;
var u8 = new Uint8Array(sigBytes);
for (var i = 0; i < sigBytes; i++) {
var byte = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
u8[i]=byte;
}
return u8;
},
parse: function (u8arr) {
var len = u8arr.length;
var words = [];
for (var i = 0; i < len; i++) {
words[i >>> 2] |= (u8arr[i] & 0xff) << (24 - (i % 4) * 8);
}
return CryptoJS.lib.WordArray.create(words, len);
}
};
But when i decrypt the file the results is empty. Ialso check the iv, salt and the encrypted message. All seems work except for the decryption that always returns an empty value.
How can i fix this problem?
Thank you!
I solved using:
var decrypted = CryptoJS.AES.decrypt({ciphertext:encrypted}, key, {
iv: iv,
padding: CryptoJS.pad.Pkcs7,
mode: CryptoJS.mode.CBC
});
in decrypt function.
Given it a long try and finally got it.
1). CryptoJS uses hex values while java uses bytes for the same String.
2.) The two other factors which need to be same (apart from the key) are initVector and padding.
Considering both above we first have to validate that both Java are CryptoJS and encrypting to the same value given the above parameters are same.
Here is the code for Java
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.util.Base64;
public class JavaEncryptor {
private static final String key = "aesEncryptionKey";
private static final String initVector = "encryptionIntVec";
public static String toHex(String arg) throws UnsupportedEncodingException {
return String.format("%020x", new BigInteger(1, arg.getBytes("UTF-8")));
}
/**
* Use these hex value in CryptoJS
* #throws Exception
*/
public static void printHexForJS() throws Exception {
System.out.println("HexKeyForJS : "+ toHex(key));
System.out.println("HexInitVectorForJS : "+ toHex(initVector));
}
public static String encrypt(String value) {
try {
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(value.getBytes());
return Base64.getEncoder().encodeToString(encrypted);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static void main(String[] args) throws Exception {
printHexForJS();
System.out.println(encrypt("MyPlainTextToBeEncrypted"));
}
}
Output of the above program is
HexKeyForJS : 616573456e6372797074696f6e4b6579
HexInitVectorForJS : 656e6372797074696f6e496e74566563
MURKOx14eSOo2vs8ZQyCpXpsoKg8Uzlvyj3byQreVBk=
And then for JS encryption use the HexKeyForJS and HexInitVectorForJS as in below code
var text = "ManishMudgal";
var key = CryptoJS.enc.Hex.parse(HexKeyForJS);
var iv = CryptoJS.enc.Hex.parse(HexInitVectorForJS);
var encrypted = CryptoJS.AES.encrypt(text, key, {iv: iv, padding: CryptoJS.pad.Pkcs7});
console.log(encrypted.toString());
Output of the above JS code should be kBgYcrSxz+kbXRnyKIFmSw==
Which is the same encrypted key generated through Java code
MURKOx14eSOo2vs8ZQyCpXpsoKg8Uzlvyj3byQreVBk=
Now Decryption at Crypto End
CryptoJS.AES.decrypt('MURKOx14eSOo2vs8ZQyCpXpsoKg8Uzlvyj3byQreVBk=', CryptoJS.enc.Hex.parse(HexKeyForJS), {iv: CryptoJS.enc.Hex.parse(HexInitVectorForJS), padding: CryptoJS.pad.Pkcs7}).toString(CryptoJS.enc.Utf8);
Cheers :)
Related
I'm using Pkcs#11 with the NCryptoki dll to use our HSM and manage the keys.
Why is this code giving me, sometimes, the error 145 (CKR_OPERATION_NOT_INITIALIZED)? I'm trying to avoid it, but I am still missing something... This error happens randomly when calling the session.Encrypt().
static public byte[] Crypto(Key key, byte[] input, bool encrypt, Mechanism mech, string command)
{
//Session session = openSession();
var tupla = openSessionTupla();
var session = tupla.Item1;
try
{
Utility.Logger("Crypto encrypt " + encrypt.ToSafeString() + " mech " + mech.ToSafeString(), command);
if (encrypt)
{
session.EncryptInit(mech, key);
byte[] enc = session.Encrypt(input);
session.EncryptFinal();
session.Logout();
session.Close();
tupla.Item2.Finalize(IntPtr.Zero);
return enc;
}
else
{
session.DecryptInit(mech, key);
byte[] decriptata = session.Decrypt(input);
session.DecryptFinal();
session.Logout();
session.Close();
tupla.Item2.Finalize(IntPtr.Zero);
return decriptata;
}
}
catch (Exception e)
{
session.Logout();
session.Close();
tupla.Item2.Finalize(IntPtr.Zero);
Utility.Logger("Crypto " + e.ToSafeString(), command);
return null;
}
}
Where openSessionTupla is
public static Tuple<Session, Cryptoki> openSessionTupla()
{
Cryptoki.Licensee = Settings.LICENSEE;
Cryptoki.ProductKey = Settings.PRODUCTKEY;
Cryptoki cryptoki = new Cryptoki(Settings.PATH);
//Console.WriteLine(Settings.PATH);
//Console.WriteLine(Settings.SessionKey);
cryptoki.Initialize();
SlotList slots = cryptoki.Slots;
if (slots.Count == 0)
{
//Console.WriteLine("No slot available");
return null;
}
// Gets the first slot available
Slot slot = slots[0];
if (!slot.IsTokenPresent)
{
//Console.WriteLine("No token inserted in the slot: " + slots[0].Info.Description);
return null;
}
Token token = slot.Token;
var flags = token.Info.Flags;
//token.Info.Flags = 1609;
Session session = token.OpenSession(Session.CKF_SERIAL_SESSION | Session.CKF_RW_SESSION,
null,
null);
int nRes = session.Login(Session.CKU_USER, Settings.SessionKey);
return new Tuple<Session, Cryptoki>(session, cryptoki);
}
Maybe the call to session.EncryptInit(mech, key) returns an error.
this is why the subsequent call to Encrypt returns CKR_OPERATION_NOT_INITIALIZED
You should write:
long nRes = session.EncryptInit(mech, key);
if(nRer != 0) {
// manage the error
}
else {
byte[] enc = session.Encrypt(input);
session.EncryptFinal();
}
var grid = $("#grid").kendoGrid({
dataSource: dataSource,
pageable: true,
height: 430,
toolbar: ["create"],
columns: [
"ProductName", {
field: "ID",
title: "Product ID",
width: "100px"
}, {
field: "UnitPrice",
title: "Unit Price",
format: "{0:c}",
width: "100px"
}, {
field: "UnitsInStock",
title: "Units In Stock",
width: "100px"
}, {
field: "Discontinued",
width: "100px"
}, {
command: ["edit", "destroy"],
title: " ",
width: "172px"
}
],
editable: "inline"
}).data("kendoGrid");
How can i encrypt column Product ID on kendo ui grid for user can't see my real id ? I'm using ASP.NET MVC 5.
Thank you !
Instead of direct Encrypting you can use kendo grid client Template for the column where you pass the Id value to the javascript function encrypt it using your algorithm and then returning it.
something like.
columns.Bound(client => client.Id).ClientTemplate("#=Encrypt(Id)#");
And
<script>
function Encrypt(id)
{
// Logic to Encrypt ID
return encryptedID.toString();
}
</script>
If this is just to show to the users then this solutions works
and second solution is to just hide the column (i mean there is no use of showing ids to the user)
If you find this helpful please mark as an answer
Enrcypt data before you load data in your code behind after that bind your data.
In order to do this use a class for encrpyt as below
public class DataEncryptor
{
TripleDESCryptoServiceProvider symm;
#region Factory
public DataEncryptor()
{
this.symm = new TripleDESCryptoServiceProvider();
this.symm.Padding = PaddingMode.PKCS7;
}
public DataEncryptor(TripleDESCryptoServiceProvider keys)
{
this.symm = keys;
}
public DataEncryptor(byte[] key, byte[] iv)
{
this.symm = new TripleDESCryptoServiceProvider();
this.symm.Padding = PaddingMode.PKCS7;
this.symm.Key = key;
this.symm.IV = iv;
}
#endregion
#region Properties
public TripleDESCryptoServiceProvider Algorithm
{
get { return symm; }
set { symm = value; }
}
public byte[] Key
{
get { return symm.Key; }
set { symm.Key = value; }
}
public byte[] IV
{
get { return symm.IV; }
set { symm.IV = value; }
}
#endregion
#region Crypto
public byte[] Encrypt(byte[] data) { return Encrypt(data, data.Length); }
public byte[] Encrypt(byte[] data, int length)
{
try
{
// Create a MemoryStream.
var ms = new MemoryStream();
// Create a CryptoStream using the MemoryStream
// and the passed key and initialization vector (IV).
var cs = new CryptoStream(ms,
symm.CreateEncryptor(symm.Key, symm.IV),
CryptoStreamMode.Write);
// Write the byte array to the crypto stream and flush it.
cs.Write(data, 0, length);
cs.FlushFinalBlock();
// Get an array of bytes from the
// MemoryStream that holds the
// encrypted data.
byte[] ret = ms.ToArray();
// Close the streams.
cs.Close();
ms.Close();
// Return the encrypted buffer.
return ret;
}
catch (CryptographicException ex)
{
Console.WriteLine("A cryptographic error occured: {0}", ex.Message);
}
return null;
}
public string EncryptString(string text)
{
return Convert.ToBase64String(Encrypt(Encoding.UTF8.GetBytes(text)));
}
public byte[] Decrypt(byte[] data) { return Decrypt(data, data.Length); }
public byte[] Decrypt(byte[] data, int length)
{
try
{
// Create a new MemoryStream using the passed
// array of encrypted data.
MemoryStream ms = new MemoryStream(data);
// Create a CryptoStream using the MemoryStream
// and the passed key and initialization vector (IV).
CryptoStream cs = new CryptoStream(ms,
symm.CreateDecryptor(symm.Key, symm.IV),
CryptoStreamMode.Read);
// Create buffer to hold the decrypted data.
byte[] result = new byte[length];
// Read the decrypted data out of the crypto stream
// and place it into the temporary buffer.
cs.Read(result, 0, result.Length);
return result;
}
catch (CryptographicException ex)
{
Console.WriteLine("A cryptographic error occured: {0}", ex.Message);
}
return null;
}
public string DecryptString(string data)
{
return Encoding.UTF8.GetString(Decrypt(Convert.FromBase64String(data))).TrimEnd('\0');
}
#endregion
}
and use it like this:
string message="A very secret message here.";
DataEncryptor keys=new DataEncryptor();
string encr=keys.EncryptString(message);
// later
string actual=keys.DecryptString(encr);
I'm using Bouncy Castle library to encrypt some data in my Windows Store App. My EncryptHelper class:
public static class EncryptHelper
{
private const string KEY = "chiaveAES";
private const int SIZE = 16;
private enum CipherMode
{
Encrypt,
Decrypt
}
private static PaddedBufferedBlockCipher InitCipher(CipherMode mode)
{
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(new AesLightEngine()), new ZeroBytePadding());
var key = new byte[32];
var keyArray = KEY.ToCharArray();
Buffer.BlockCopy(keyArray, 0, key, 0, Math.Min(keyArray.Length, key.Length));
cipher.Init(mode == CipherMode.Encrypt, new KeyParameter(key));
return cipher;
}
public static async Task Encrypt(Stream sourceStream, Stream destinationStream, bool autoSeekStart = true, bool autoSeekEnd = true)
{
//await Process(InitCipher(CipherMode.Encrypt), sourceStream, destinationStream, autoSeekStart, autoSeekEnd);
await ProcessBlocks(InitCipher(CipherMode.Encrypt), sourceStream, destinationStream, autoSeekStart, autoSeekEnd);
}
public static async Task Decrypt(Stream sourceStream, Stream destinationStream, bool autoSeekStart = true, bool autoSeekEnd = true)
{
//await Process(InitCipher(CipherMode.Decrypt), sourceStream, destinationStream, autoSeekStart, autoSeekEnd);
await ProcessBlocks(InitCipher(CipherMode.Decrypt), sourceStream, destinationStream, autoSeekStart, autoSeekEnd);
}
private static async Task Process(PaddedBufferedBlockCipher cipher, Stream sourceStream, Stream destinationStream, bool autoSeekStart, bool autoSeekEnd)
{
if (autoSeekStart)
{
sourceStream.ToBegin();
destinationStream.ToBegin();
}
var size = Convert.ToInt16(sourceStream.Length);
byte[] inBuffer = new byte[size];
byte[] outBuffer = new byte[cipher.GetOutputSize(size)];
int inCount = 0;
int outCount = 0;
try
{
inCount = await sourceStream.ReadAsync(inBuffer, 0, inBuffer.Length);
outCount = cipher.ProcessBytes(inBuffer, 0, inCount, outBuffer, 0);
outCount += cipher.DoFinal(outBuffer, outCount);
await destinationStream.WriteAsync();
await destinationStream.FlushAsync();
}
catch { }
if (autoSeekEnd)
{
sourceStream.ToBegin();
destinationStream.ToBegin();
}
}
private static async Task ProcessBlocks(PaddedBufferedBlockCipher cipher, Stream sourceStream, Stream destinationStream, bool autoSeekStart, bool autoSeekEnd)
{
if (autoSeekStart)
{
sourceStream.ToBegin();
destinationStream.ToBegin();
}
byte[] inBuffer = new byte[SIZE];
byte[] outBuffer = new byte[cipher.GetOutputSize(SIZE)];
int inCount = 0;
int outCount = 0;
try
{
while ((inCount = await sourceStream.ReadAsync(inBuffer, 0, inBuffer.Length)) > 0)
{
outCount += cipher.ProcessBytes(inBuffer, 0, inCount, outBuffer, 0);
await destinationStream.WriteAsync(outBuffer, 0, outBuffer.Length);
}
outBuffer = ?
outCount += cipher.DoFinal(outBuffer, outCount);
await destinationStream.WriteAsync(outBuffer, 0, outCount);
await destinationStream.FlushAsync();
}
catch { }
if (autoSeekEnd)
{
sourceStream.ToBegin();
destinationStream.ToBegin();
}
}
}
My Process() method works fine, but when on the instruction
inCount = await sourceStream.ReadAsync(inBuffer, 0, inBuffer.Length);
I'm afraid it may occurr an OutOfMemoryException if the stream has too much data. So, I was trying to build the ProcessBlocks() method, which should read from the stream progressively, one block per time, without overcharging the RAM. I have some doubts on how to behave with outBuffer: it should be overwritten in every cycle in which cipher.ProcessBytes() gets executed, but of which size should it be just before the cipher.DoFinal() invocation?
Thank you
UPDATE 30/07/2015
I modified the Main in the answer to handle a zip file and the outcoming zip file is no more a valid ZIP, could someone explain me why?
public static void Main(string[] args)
{
var plainPath = #"C:\Users\Federico\Desktop\0abed72d-defc-4c9a-a8ae-3fec43f01224.zip";
var decryptPath = #"C:\Users\Federico\Desktop\0abed72d-defc-4c9a-a8ae-3fec43f01224 - decrypted.zip";
var plainStream = new FileStream(plainPath, FileMode.Open, FileAccess.Read);
var cipherStream = new MemoryStream();
EncryptHelper.Encrypt(plainStream, cipherStream);
cipherStream.Seek(0, SeekOrigin.Begin);
FileStream fs = new FileStream(decryptPath, FileMode.Create);
EncryptHelper.Decrypt(cipherStream, fs);
fs.Flush();
fs.Close();
}
cipher.DoFinal() will produce as many as 2 * Cipher.GetBlockSize() bytes. The actual number of bytes produced is returned by the method.
Here is an example that is loosely based on your example.
using System;
using System.IO;
using Org.BouncyCastle.Crypto.Paddings;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Engines;
using System.Text;
namespace PaddedBufferedBlockCipherExample
{
public class EncryptHelper
{
private const string KEY = "chiaveAES";
private const int BufferSize = 1024;
private PaddedBufferedBlockCipher cipher;
public enum CipherMode
{
Encrypt,
Decrypt
}
public EncryptHelper (CipherMode mode)
{
cipher = new PaddedBufferedBlockCipher (new CbcBlockCipher (new AesLightEngine ()), new Pkcs7Padding ());
var key = new byte[32];
var keyArray = KEY.ToCharArray ();
Buffer.BlockCopy (keyArray, 0, key, 0, Math.Min (keyArray.Length, key.Length));
cipher.Init (mode == CipherMode.Encrypt, new KeyParameter (key));
}
public static void Encrypt (Stream sourceStream, Stream destinationStream)
{
var helper = new EncryptHelper (CipherMode.Encrypt);
helper.ProcessBlocks (sourceStream, destinationStream);
}
public static void Decrypt (Stream sourceStream, Stream destinationStream)
{
var helper = new EncryptHelper (CipherMode.Decrypt);
helper.ProcessBlocks (sourceStream, destinationStream);
}
private void ProcessBlocks (Stream sourceStream, Stream destinationStream)
{
// inBuffer is sized for efficient I/O
var inBuffer = new byte[BufferSize];
// outBuffer should be large enough to not require further resizing
var outBuffer = new byte[cipher.GetBlockSize() + cipher.GetOutputSize (inBuffer.Length)];
int inCount = 0;
int outCount = 0;
// Process data using the cipher.ProcessBytes method, until we reach EOF
while ((inCount = sourceStream.Read (inBuffer, 0, inBuffer.Length)) > 0) {
outCount = cipher.ProcessBytes (inBuffer, 0, inCount, outBuffer, 0);
destinationStream.Write (outBuffer, 0, outCount);
}
// Now "flush" the cipher instance by calling the DoFinal method. This
// will finish the en/de-cryption by ciphering any buffered data and processing any
// encryption padding.
outCount = cipher.DoFinal (outBuffer, 0);
destinationStream.Write (outBuffer, 0, outCount);
}
public static void Main (string[] args)
{
var plainPath = "/Users/robert/src/csharp_toys/toy1/Program.cs";
var plainStream = new FileStream (plainPath, FileMode.Open, FileAccess.Read);
var cipherStream = new MemoryStream ();
EncryptHelper.Encrypt (plainStream, cipherStream);
cipherStream.Seek (0, SeekOrigin.Begin);
var decryptedStream = new MemoryStream ();
EncryptHelper.Decrypt (cipherStream, decryptedStream);
var decryptedString = Encoding.ASCII.GetString (decryptedStream.ToArray ());
Console.Write (decryptedString);
}
}
}
UPDATE 30/07/2015
I found out it was just a padding problem, I used ZeroBytePadding and it messed up everything.
I would like to do AES Encryption in C# and decryption in CryptoJS.
It is working now after getting some reference from Google CryptoJS group (https://groups.google.com/forum/#!msg/crypto-js/ysgzr2Wxt_k/_Wh8l_1rhQAJ).
Here is encryption code in C#.NET.
public class ClsCrypto
{
private RijndaelManaged myRijndael = new RijndaelManaged();
private int iterations;
private byte [] salt;
public ClsCrypto(string strPassword)
{
myRijndael.BlockSize = 128;
myRijndael.KeySize = 128;
myRijndael.IV = HexStringToByteArray("e84ad660c4721ae0e84ad660c4721ae0");
myRijndael.Padding = PaddingMode.PKCS7;
myRijndael.Mode = CipherMode.CBC;
iterations = 1000;
salt = System.Text.Encoding.UTF8.GetBytes("insight123resultxyz");
myRijndael.Key = GenerateKey(strPassword);
}
public string Encrypt(string strPlainText)
{
byte [] strText = new System.Text.UTF8Encoding().GetBytes(strPlainText);
ICryptoTransform transform = myRijndael.CreateEncryptor();
byte [] cipherText = transform.TransformFinalBlock(strText, 0, strText.Length);
return Convert.ToBase64String(cipherText);
}
public string Decrypt(string encryptedText)
{
byte[] encryptedBytes = Convert.FromBase64String(encryptedText);
var decryptor = myRijndael.CreateDecryptor(myRijndael.Key, myRijndael.IV);
byte[] originalBytes = decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
return Encoding.UTF8.GetString(originalBytes);
}
public static byte [] HexStringToByteArray(string strHex)
{
dynamic r = new byte[strHex.Length / 2];
for (int i = 0; i <= strHex.Length - 1; i += 2)
{
r[i/2] = Convert.ToByte(Convert.ToInt32(strHex.Substring(i, 2), 16));
}
return r;
}
private byte[] GenerateKey(string strPassword)
{
Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(System.Text.Encoding.UTF8.GetBytes(strPassword), salt, iterations);
return rfc2898.GetBytes(128 / 8);
}
}
Following is decryption code in Java script.
<head runat="server">
<script src="rollups/aes.js" type="text/javascript"></script>
<script src="rollups/sha256.js" type="text/javascript"></script>
<script src="rollups/pbkdf2.js" type="text/javascript"></script>
<script type="text/javascript">
function DecryptData() {
var encryptData = document.getElementById('TextEncrypted').value;
var decryptElement = document.getElementById('TextDecrypt');
try {
//Creating the Vector Key
var iv = CryptoJS.enc.Hex.parse('e84ad660c4721ae0e84ad660c4721ae0');
//Encoding the Password in from UTF8 to byte array
var Pass = CryptoJS.enc.Utf8.parse('insightresult');
//Encoding the Salt in from UTF8 to byte array
var Salt = CryptoJS.enc.Utf8.parse("insight123resultxyz");
//Creating the key in PBKDF2 format to be used during the decryption
var key128Bits1000Iterations = CryptoJS.PBKDF2(Pass.toString(CryptoJS.enc.Utf8), Salt, { keySize: 128 / 32, iterations: 1000 });
//Enclosing the test to be decrypted in a CipherParams object as supported by the CryptoJS libarary
var cipherParams = CryptoJS.lib.CipherParams.create({
ciphertext: CryptoJS.enc.Base64.parse(encryptData)
});
//Decrypting the string contained in cipherParams using the PBKDF2 key
var decrypted = CryptoJS.AES.decrypt(cipherParams, key128Bits1000Iterations, { mode: CryptoJS.mode.CBC, iv: iv, padding: CryptoJS.pad.Pkcs7 });
decryptElement.value = decrypted.toString(CryptoJS.enc.Utf8);
}
//Malformed UTF Data due to incorrect password
catch (err) {
return "";
}
}
</script>
</head>
while encrypting and descripting the string with rsa provider I am getting this error.
RSA Data decryption error.The data to be decrypted exceeds the maximum for this modulus of 64 bytes.
Can any one have idea how to slove this error?
internal sealed class RSAProvider
{
#region key store class
[Serializable]
private struct rsaKey
{
public rsaKey(RSAParameters rsaKeyInfo)
{
D = rsaKeyInfo.D;
DP = rsaKeyInfo.DP;
DQ = rsaKeyInfo.DQ;
Exponent = rsaKeyInfo.Exponent;
InverseQ = rsaKeyInfo.InverseQ;
Modulus = rsaKeyInfo.Modulus;
P = rsaKeyInfo.P;
Q = rsaKeyInfo.Q;
}
public RSAParameters CreateRSAKey()
{
RSAParameters rsaKeyInfo = new RSAParameters();
rsaKeyInfo.D = D;
rsaKeyInfo.DP = DP;
rsaKeyInfo.DQ = DQ;
rsaKeyInfo.Exponent = Exponent;
rsaKeyInfo.InverseQ = InverseQ;
rsaKeyInfo.Modulus = Modulus;
rsaKeyInfo.P = P;
rsaKeyInfo.Q = Q;
return rsaKeyInfo;
}
public byte[] D;
public byte[] DP;
public byte[] DQ;
public byte[] Exponent;
public byte[] InverseQ;
public byte[] Modulus;
public byte[] P;
public byte[] Q;
}
#endregion
private static RSAParameters rsaKeyParameters;
static RSAProvider()
{
string rsaKeyString = System.Configuration.ConfigurationSettings.AppSettings["RSAKey"];
if(rsaKeyString != null)
{
rsaKeyParameters = GetKeyByString(rsaKeyString);
}
}
private RSAProvider()
{
}
private static RSAParameters RSAKeyInfo
{
get
{
return rsaKeyParameters;
}
}
private static bool DoOAEPPadding
{
get
{
return false;
}
}
public static string GenerateKey(int keySize)
{
//Create a new instance of RSACryptoServiceProvider to generate
//public and private key data.
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(keySize);
RSAParameters rsaKeyInfo = RSA.ExportParameters(true);
return GetKeyString(rsaKeyInfo);
}
#region Encrypt
public static byte[] Encrypt(byte[] dataToEncrypt, string rsaKeyString)
{
RSAParameters rsaKeyInfo = GetKeyByString(rsaKeyString);
return Encrypt(dataToEncrypt, rsaKeyInfo);
}
public static byte[] Encrypt(byte[] dataToEncrypt, RSAParameters rsaKeyInfo)
{
try
{
//Create a new instance of RSACryptoServiceProvider.
// Common.Identity.ImpersonateValidUser("prana", "eetplpvt", "Avdhoota1985");
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
//Import the RSA Key information. This only needs
//toinclude the public key information.
RSA.ImportParameters(rsaKeyInfo);
//Encrypt the passed byte array and specify OAEP padding.
//OAEP padding is only available on Microsoft Windows XP or
//later.
//return RSA.Encrypt(dataToEncrypt, DoOAEPPadding);
byte[] data = RSA.Encrypt(dataToEncrypt, DoOAEPPadding);
RSA.Clear();
//Common.Identity.UndoImpersonation();
return data;
}
//Catch and display a CryptographicException
//to the console.
catch(CryptographicException e)
{
// Updated By Divya Bhalodia on 27th June 2008 for Localization task
//throw new Exception("Data encryption error.", e);
Common.EnumLocalization.EnumLocalization loc = new Common.EnumLocalization.EnumLocalization(ASP.BL.ApplicationUsers.ApplicationUserController.CurrentUserCulture.Code, ASP.BL.Applications.ApplicationController.CurrentApplicationInfo.ItemId);
throw new Exception(loc.LocalizeString("RSA Data encryption error.") + e.Message, e);
// end Updated - Divya
}
}
public static byte[] Encrypt(byte[] dataToEncrypt)
{
return Encrypt(dataToEncrypt, RSAKeyInfo);
}
#endregion
#region Decrypt
public static byte[] Decrypt(byte[] dataToDecrypt, string rsaKeyString, bool doOAEPPadding)
{
RSAParameters rsaKeyInfo = GetKeyByString(rsaKeyString);
return Decrypt(dataToDecrypt, rsaKeyInfo, doOAEPPadding);
}
public static byte[] Decrypt(byte[] dataToDecrypt, RSAParameters rsaKeyInfo, bool doOAEPPadding)
{
try
{
//Create a new instance of RSACryptoServiceProvider.
Common.Identity.ImpersonateValidUser();
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
//Import the RSA Key information. This needs
//to include the private key information.
RSA.ImportParameters(rsaKeyInfo);
//Decrypt the passed byte array and specify OAEP padding.
//OAEP padding is only available on Microsoft Windows XP or
//later.
//return RSA.Decrypt(dataToDecrypt, doOAEPPadding);
byte[] data = RSA.Decrypt(dataToDecrypt, doOAEPPadding);
RSA.Clear();
Common.Identity.UndoImpersonation();
return data;
}
//Catch and display a CryptographicException
//to the console.
catch(CryptographicException e)
{
// Updated By Divya Bhalodia on 27th June 2008 for Localization task
//throw new Exception("Data decryption error.", e);
Common.EnumLocalization.EnumLocalization loc = new Common.EnumLocalization.EnumLocalization(ASP.BL.ApplicationUsers.ApplicationUserController.CurrentUserCulture.Code, ASP.BL.Applications.ApplicationController.CurrentApplicationInfo.ItemId);
throw new Exception(loc.LocalizeString("RSA Data decryption error.") + e.Message, e);
// end Updated - Divya
}
}
public static byte[] Decrypt(byte[] dataToDecrypt)
{
return Decrypt(dataToDecrypt, RSAKeyInfo, DoOAEPPadding);
}
#endregion
#region Additional functions
private static string GetKeyString(RSAParameters rsaKeyInfo)
{
byte[] tmp;
rsaKey k = new rsaKey(rsaKeyInfo);
BinaryFormatter formater = new BinaryFormatter();
using(MemoryStream stream = new MemoryStream())
{
formater.Serialize(stream, k);
tmp = stream.ToArray();
}
Code(tmp);
return Convert.ToBase64String(tmp);
}
private static RSAParameters GetKeyByString(string rsaKeyString)
{
rsaKey k;
byte[] tmp = Convert.FromBase64String(rsaKeyString);
Code(tmp);
BinaryFormatter formater = new BinaryFormatter();
using(MemoryStream stream = new MemoryStream(tmp))
{
k = (rsaKey)formater.Deserialize(stream);
}
return k.CreateRSAKey();
}
private static void Code(byte[] tmp)
{
byte mask1 = 0x55;
byte mask3 = 0xB9;
byte mask4 = 0xCF;
for(int i = 0; i
I've encoutered similar problems but you can do two things to help yourself overcome them.
You need to ensure that hte data you are encrypting is shorter than the key that you are using. so if your key is 1024 bits then make sure that you are only bassing in say 1000 bits. To do this you need to get chunk your byte array into smaller chunks, encrypt each chunk and then store the encrypeted value in an array or a string. So instead of encrypting 1 string you encrypt say 5 strings.
When storing this information as a string make sure that all numbers are the same length, so if the formatter returns 15 you store the string with 015 so that you just divide by 3 later to get the byte to then put into the array.
To decrypt your data you need to simply read the length of the string and determine how many chunks to decrypt. Decrupt these one by one and then you can recreate the object with the decrupted byte array.
if you would like actual code please contact me personally and I'll be able to help you better with some script that can do this for you.