asp.net mvc kendo ui grid encrypt column data - asp.net

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);

Related

How to send a zipped file to S3 bucket from Apex?

Folks,
I am trying to move data to s3 from Salesforce using apex class. I have been told by the data manager to send the data in zip/gzip format to the S3 bucket for storage cost savings.
I have simply tried to do a request.setCompressed(true); as I've read it compresses the body before sending it to the endpoint. Code below:
HttpRequest request = new HttpRequest();
request.setEndpoint('callout:'+DATA_NAMED_CRED+'/'+URL+'/'+generateUniqueTimeStampforSuffix());
request.setMethod('PUT');
request.setBody(JSON.serialize(data));
request.setCompressed(true);
request.setHeader('Content-Type','application/json');
But no matter what I always receive this:
<Error><Code>XAmzContentSHA256Mismatch</Code><Message>The provided 'x-amz-content-sha256' header does not match what was computed.</Message><ClientComputedContentSHA256>fd31b2b9115ef77e8076b896cb336d21d8f66947210ffcc9c4d1971b2be3bbbc</ClientComputedContentSHA256><S3ComputedContentSHA256>1e7f2115e60132afed9e61132aa41c3224c6e305ad9f820e6893364d7257ab8d</S3ComputedContentSHA256>
I have tried multiple headers too, like setting the content type to gzip/zip, etc.
Any pointers in the right direction would be appreciated.
I had a good amount of headaches attempting to do a similar thing. I feel your pain.
The following code has worked for us using lambda functions; you can try modifying it and see what happens.
public class AwsApiGateway {
// Things we need to know about the service. Set these values in init()
String host, payloadSha256;
String resource;
String service = 'execute-api';
String region;
public Url endpoint;
String accessKey;
String stage;
string secretKey;
HttpMethod method = HttpMethod.XGET;
// Remember to set "payload" here if you need to specify a body
// payload = Blob.valueOf('some-text-i-want-to-send');
// This method helps prevent leaking secret key,
// as it is never serialized
// Url endpoint;
// HttpMethod method;
Blob payload;
// Not used externally, so we hide these values
Blob signingKey;
DateTime requestTime;
Map<String, String> queryParams = new map<string,string>(), headerParams = new map<string,string>();
void init(){
if (payload == null) payload = Blob.valueOf('');
requestTime = DateTime.now();
createSigningKey(secretKey);
}
public AwsApiGateway(String resource){
this.stage = AWS_LAMBDA_STAGE
this.resource = '/' + stage + '/' + resource;
this.region = AWS_REGION;
this.endpoint = new Url(AWS_ENDPOINT);
this.accessKey = AWS_ACCESS_KEY;
this.secretKey = AWS_SECRET_KEY;
}
// Make sure we can't misspell methods
public enum HttpMethod { XGET, XPUT, XHEAD, XOPTIONS, XDELETE, XPOST }
public void setMethod (HttpMethod method){
this.method = method;
}
public void setPayload (string payload){
this.payload = Blob.valueOf(payload);
}
// Add a header
public void setHeader(String key, String value) {
headerParams.put(key.toLowerCase(), value);
}
// Add a query param
public void setQueryParam(String key, String value) {
queryParams.put(key.toLowerCase(), uriEncode(value));
}
// Create a canonical query string (used during signing)
String createCanonicalQueryString() {
String[] results = new String[0], keys = new List<String>(queryParams.keySet());
keys.sort();
for(String key: keys) {
results.add(key+'='+queryParams.get(key));
}
return String.join(results, '&');
}
// Create the canonical headers (used for signing)
String createCanonicalHeaders(String[] keys) {
keys.addAll(headerParams.keySet());
keys.sort();
String[] results = new String[0];
for(String key: keys) {
results.add(key+':'+headerParams.get(key));
}
return String.join(results, '\n')+'\n';
}
// Create the entire canonical request
String createCanonicalRequest(String[] headerKeys) {
return String.join(
new String[] {
method.name().removeStart('X'), // METHOD
new Url(endPoint, resource).getPath(), // RESOURCE
createCanonicalQueryString(), // CANONICAL QUERY STRING
createCanonicalHeaders(headerKeys), // CANONICAL HEADERS
String.join(headerKeys, ';'), // SIGNED HEADERS
payloadSha256 // SHA256 PAYLOAD
},
'\n'
);
}
// We have to replace ~ and " " correctly, or we'll break AWS on those two characters
string uriEncode(String value) {
return value==null? null: EncodingUtil.urlEncode(value, 'utf-8').replaceAll('%7E','~').replaceAll('\\+','%20');
}
// Create the entire string to sign
String createStringToSign(String[] signedHeaders) {
String result = createCanonicalRequest(signedHeaders);
return String.join(
new String[] {
'AWS4-HMAC-SHA256',
headerParams.get('date'),
String.join(new String[] { requestTime.formatGMT('yyyyMMdd'), region, service, 'aws4_request' },'/'),
EncodingUtil.convertToHex(Crypto.generateDigest('sha256', Blob.valueof(result)))
},
'\n'
);
}
// Create our signing key
void createSigningKey(String secretKey) {
signingKey = Crypto.generateMac('hmacSHA256', Blob.valueOf('aws4_request'),
Crypto.generateMac('hmacSHA256', Blob.valueOf(service),
Crypto.generateMac('hmacSHA256', Blob.valueOf(region),
Crypto.generateMac('hmacSHA256', Blob.valueOf(requestTime.formatGMT('yyyyMMdd')), Blob.valueOf('AWS4'+secretKey))
)
)
);
}
// Create all of the bits and pieces using all utility functions above
public HttpRequest createRequest() {
init();
payloadSha256 = EncodingUtil.convertToHex(Crypto.generateDigest('sha-256', payload));
setHeader('date', requestTime.formatGMT('yyyyMMdd\'T\'HHmmss\'Z\''));
if(host == null) {
host = endpoint.getHost();
}
setHeader('host', host);
HttpRequest request = new HttpRequest();
request.setMethod(method.name().removeStart('X'));
if(payload.size() > 0) {
setHeader('Content-Length', String.valueOf(payload.size()));
request.setBodyAsBlob(payload);
}
String finalEndpoint = new Url(endpoint, resource).toExternalForm(),
queryString = createCanonicalQueryString();
if(queryString != '') {
finalEndpoint += '?'+queryString;
}
request.setEndpoint(finalEndpoint);
for(String key: headerParams.keySet()) {
request.setHeader(key, headerParams.get(key));
}
String[] headerKeys = new String[0];
String stringToSign = createStringToSign(headerKeys);
request.setHeader(
'Authorization',
String.format(
'AWS4-HMAC-SHA256 Credential={0}, SignedHeaders={1},Signature={2}',
new String[] {
String.join(new String[] { accessKey, requestTime.formatGMT('yyyyMMdd'), region, service, 'aws4_request' },'/'),
String.join(headerKeys,';'), EncodingUtil.convertToHex(Crypto.generateMac('hmacSHA256', Blob.valueOf(stringToSign), signingKey))}
));
system.debug(json.serializePretty(request.getEndpoint()));
return request;
}
// Actually perform the request, and throw exception if response code is not valid
public HttpResponse sendRequest(Set<Integer> validCodes) {
HttpResponse response = new Http().send(createRequest());
if(!validCodes.contains(response.getStatusCode())) {
system.debug(json.deserializeUntyped(response.getBody()));
}
return response;
}
// Same as above, but assume that only 200 is valid
// This method exists because most of the time, 200 is what we expect
public HttpResponse sendRequest() {
return sendRequest(new Set<Integer> { 200 });
}
// TEST METHODS
public static string getEndpoint(string attribute){
AwsApiGateway api = new AwsApiGateway(attribute);
return api.createRequest().getEndpoint();
}
public static string getEndpoint(string attribute, map<string, string> params){
AwsApiGateway api = new AwsApiGateway(attribute);
for (string key: params.keySet()){
api.setQueryParam(key, params.get(key));
}
return api.createRequest().getEndpoint();
}
public class EndpointConfig {
string resource;
string attribute;
list<object> items;
map<string,string> params;
public EndpointConfig(string resource, string attribute, list<object> items){
this.items = items;
this.resource = resource;
this.attribute = attribute;
}
public EndpointConfig setQueryParams(map<string,string> parameters){
params = parameters;
return this;
}
public string endpoint(){
if (params == null){
return getEndpoint(resource);
} else return getEndpoint(resource + '/' + attribute, params);
}
public SingleRequestMock mockResponse(){
return new SingleRequestMock(200, 'OK', json.serialize(items), null);
}
}
}

Passing images from one page to another in Xamarin Forms

In my app I need to pass images from one page to another page image view to display. I am taking a photo from camera and do some stuffs, then I want to send that images to the second page.
if (await isCamAvailable())
{
MediaFile photo1 = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions() { Directory = "NewBusiness", Name = "image1.jpg", PhotoSize = PhotoSize.MaxWidthHeight, MaxWidthHeight = 1024, CompressionQuality = 95 });
if (photo1 != null)
{
PhotoImage1.Source = ImageSource.FromStream(() => { return photo1.GetStream(); });
countList.Remove("a");
countList.Add("a");
}
}
Then I am added it to a string array by doing
private List<string> sendImgList = new List<string>();
sendImgList.Add(createImgByteString(photo1.GetStream()));
private string createImgByteString(Stream data)
{
var bytes = new byte[data.Length];
return Convert.ToBase64String(bytes);
}
Then from second page (for testing i just added only one image)
foreach (string ss in imgList) {
byte[] Base64Stream = Convert.FromBase64String(ss);
imgView.Source = ImageSource.FromStream(() => new MemoryStream(Base64Stream));
}
I followed this example. But image not showing.
https://forums.xamarin.com/discussion/139360/how-to-transfer-images-from-one-page-to-another
Also getting this in logcat..
[0:] ImageLoaderSourceHandler: Image data was invalid: Xamarin.Forms.StreamImageSource05-29 14:22:43.758 W/monodroid-assembly( 8737): typemap: unable to find mapping to a Java type from managed type 'System.Byte, mscorlib'
It seems that you used the Media.Plugin . Why don't you pass the ImageSource directly?
If you do want to convert it to byte array , check the following code
public byte[] GetImageStreamAsBytes(Stream input)
{
var buffer = new byte[16*1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
var imgDate = GetImageStreamAsBytes(photo1.GetStream());
It would be better to pass the byte array directly .
The best mode to pass parameter in pages is with Prism.
https://prismlibrary.com/docs/xamarin-forms/navigation/passing-parameters.html
>
_navigationService.NavigateAsync(new Uri("MainPage", new NavigationParameters
{
{ "key_parameter", image }
})));
And on other page:
>
public override void OnNavigatedTo(INavigationParameters parameters)
{
image = (Image)parameters["key_parameter"];
}

How to save an image in SQLite in Xamarin Forms?

I have the following two methods that handles taking photos from a camera and picking photos from a library. They're both similar methods as at the end of each method, I get an ImageSource back from the Stream and I pass it onto another page which has an ImageSource binding ready to be set. These two method work perfectly. The next step now is to save the Image in SQLite so I can show the images in a ListView later on. My question for the XamGods (Xamarin Pros =), what is the best way to save image in SQLite in 2019? I have been in the forums for hours and I still don't have a tunnel vision on what I want to do. I can either
Convert Stream into an array of bytes to save in Sqlite.
Convert ImageSource into an array of bytes (messy/buggy).
Somehow retrieve the actual Image selected/taken and convert that into an array of bytes into SQLite
I'm sorry if my question is general, but Xamarin does not provide a clear-cut solution on how to save images in SQLite and you can only find bits and pieces of solutions throughout the forums listed below.
How to save and retrieve Image from Sqlite
Load Image from byte[] array.
Creating a byte array from a stream
Thank you in advance!
private async Task OnAddPhotoFromCameraSelected()
{
Console.WriteLine("OnAddPhotoFromCameraSelected");
var photo = await Plugin.Media.CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions() { });
var stream = photo.GetStream();
photo.Dispose();
if (stream != null)
{
ImageSource cameraPhotoImage = ImageSource.FromStream(() => stream);
var parms = new NavigationParameters();
parms.Add("image", cameraPhotoImage);
var result = await NavigationService.NavigateAsync("/AddInspectionPhotoPage?", parameters: parms);
if (!result.Success)
{
throw result.Exception;
}
}
}
private async Task OnAddPhotoFromLibrarySelected()
{
Console.WriteLine("OnAddPhotoFromLibrarySelected");
Stream stream = await DependencyService.Get<IPhotoPickerService>().GetImageStreamAsync();
if (stream != null)
{
ImageSource selectedImage = ImageSource.FromStream(() => stream);
var parms = new NavigationParameters();
parms.Add("image", selectedImage);
parms.Add("stream", stream);
var result = await NavigationService.NavigateAsync("/AddInspectionPhotoPage?", parameters: parms);
if (!result.Success)
{
throw result.Exception;
}
}
}
As Jason said that you can save image path into sqlite database, but if you still want to save byte[] into sqlite database, you need to convert stream into byte[] firstly:
private byte[] GetImageBytes(Stream stream)
{
byte[] ImageBytes;
using (var memoryStream = new System.IO.MemoryStream())
{
stream.CopyTo(memoryStream);
ImageBytes = memoryStream.ToArray();
}
return ImageBytes;
}
Then load byte[] from sqlite, converting into stream.
public Stream BytesToStream(byte[] bytes)
{
Stream stream = new MemoryStream(bytes);
return stream;
}
For simple sample, you can take a look:
Insert byte[] in sqlite:
private void insertdata()
{
var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "sqlite1.db3");
using (var con = new SQLiteConnection(path))
{
Image image = new Image();
image.Content = ConvertStreamtoByte();
var result = con.Insert(image);
sl.Children.Add(new Label() { Text = result > 0 ? "insert successful insert" : "fail insert" });
}
}
Loading image from sqlite:
private void getdata()
{
var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "sqlite1.db3");
using (var con = new SQLiteConnection(path))
{
var image= con.Query<Image>("SELECT content FROM Image ;").FirstOrDefault();
if(image!=null)
{
byte[] b = image.Content;
Stream ms = new MemoryStream(b);
image1.Source = ImageSource.FromStream(() => ms);
}
}
}
Model:
public class Image
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string FileName { get; set; }
public byte[] Content { get; set; }
}

AES decryption returning empty string

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 :)

RSA Data decryption error.The data to be decrypted exceeds the maximum for this modulus of 64 bytes

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.

Resources