Related
I have gone through many posts here but did not find the right solution. I want to decrypt a value encrypted in c# .net from Android.
I have successfully decrypted in .net platform using the following code snippet
public static void Main()
{
string _privateKey = Base64Decode("myprivatekey");
var rsa = new RSACryptoServiceProvider();
string data = "198,47,144,175,154,47,194,175,242,41,212,150,220,177,198,161,236,36,197,62,18,111,21,244,232,245,90,234,195,169,141,195,139,199,131,163,26,124,246,50,102,229,73,148,18,110,170,145,112,237,23,123,226,135,158,206,71,116,9,219,56,96,140,19,180,192,80,29,63,160,43,127,204,135,155,67,46,160,225,12,85,161,107,214,104,218,6,220,252,73,252,92,152,235,214,126,245,126,129,150,49,68,162,120,237,246,27,25,45,225,106,201,251,128,243,213,250,172,26,28,176,219,198,194,7,202,34,210";
var dataArray = data.Split(new char[] { ',' });
byte[] dataByte = new byte[dataArray.Length];
for (int i = 0; i < dataArray.Length; i++)
{
dataByte[i] = Convert.ToByte(dataArray[i]);
}
rsa.FromXmlString(_privateKey);
var decryptedByte = rsa.Decrypt(dataByte, false);
Console.WriteLine(_encoder.GetString(decryptedByte));
}
Now I want to do the same process in Android app. Please can somebody guide me through this?
I have tried the following code but its throwing javax.crypto.IllegalBlockSizeException: input must be under 128 bytes exception
String modulusString = "hm2oRCtP6usJKYpq7o1K20uUuL11j5xRrbV4FCQhn/JeXLT21laKK9901P69YUS3bLo64x8G1PkCfRtjbbZCIaa1Ci/BCQX8nF2kZVfrPyzcmeAkq4wsDthuZ+jPInknzUI3TQPAzdj6gim97E731i6WP0MHFqW6ODeQ6Dsp8pc=";
String publicExponentString = "AQAB";
byte[] modulusBytes = Base64.decode(modulusString, DEFAULT);
byte[] exponentBytes = Base64.decode(publicExponentString, DEFAULT);
BigInteger modulus = new BigInteger(1, modulusBytes);
BigInteger publicExponent = new BigInteger(1, exponentBytes);
RSAPrivateKeySpec rsaPubKey = new RSAPrivateKeySpec(modulus, publicExponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
PrivateKey pubKey = fact.generatePrivate(rsaPubKey);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] plainBytes = result.getBytes("UTF-16LE");
byte[] cipherData = cipher.doFinal(plainBytes);
String encryptedStringBase64 = Base64.decode(cipherData, DEFAULT).toString();
I have the code below that works with 128 bit Hex Key. However, when i supply 256 bit Hex key (or higher) it throws error
Message: System.ArgumentException : Specified key is not a valid size
for this algorithm. Parameter name: rgbKey
public static string Encrypt(string text, string keyString)
{
var key = Encoding.UTF8.GetBytes(keyString);
using (var aesAlg = Aes.Create())
{
using (var encryptor = aesAlg.CreateEncryptor(key, aesAlg.IV))
{
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(text);
}
var iv = aesAlg.IV;
var decryptedContent = msEncrypt.ToArray();
var result = new byte[iv.Length + decryptedContent.Length];
Buffer.BlockCopy(iv, 0, result, 0, iv.Length);
Buffer.BlockCopy(decryptedContent, 0, result, iv.Length, decryptedContent.Length);
return Convert.ToBase64String(result);
}
}
}
}
How do i use AES with 256 bit or higher Key?
Try setting the Padding mode to PKCS7.
aesAlg.Padding = PaddingMode.PKCS7.
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 :)
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.
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.