RSA example that do not use NoPadding - java

Where can I find a RSA encrypt example that does not use "NoPadding"?
--update
Better: how to make this SSCCE run correctly without throw the "too much data for RSA block" exception?
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import javax.crypto.Cipher;
/**
* Basic RSA example.
*/
public class TestRSA {
public static void main(String[] args) throws Exception {
byte[] input = new byte[100];
Cipher cipher = Cipher.getInstance("RSA/None/NoPadding", "BC");
KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");
// create the keys
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger("d46f473a2d746537de2056ae3092c451",
16), new BigInteger("11", 16));
RSAPrivateKeySpec privKeySpec = new RSAPrivateKeySpec(new BigInteger(
"d46f473a2d746537de2056ae3092c451", 16), new BigInteger("57791d5430d593164082036ad8b29fb1",
16));
RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(pubKeySpec);
RSAPrivateKey privKey = (RSAPrivateKey) keyFactory.generatePrivate(privKeySpec);
// encryption step
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] cipherText = cipher.doFinal(input);
// decryption step
cipher.init(Cipher.DECRYPT_MODE, privKey);
byte[] plainText = cipher.doFinal(cipherText);
}
}
--update: about loop
Using:
byte[] cipherText = new byte[input.length];
for (int i = 0; i < input.length; i++) {
byte[] singleByteArray = new byte[] { input[i] };
cipherText[i] = cipher.doFinal(singleByteArray)[0];
}
does not work fine. For a unknown reason the cipherText became full of zeros - even if the input is an array of 0x03.

The Sun Providers Documentation for the SunJCE provider tells you what padding specifications are allowed in the Cipher.getInstance() argument. Try Cipher.getInstance("RSA/ECB/PKCS1PADDING");
EDIT:
It is not a padding issue, it is more that you have a misunderstanding of how RSA is used in cryptography. You can either 1) make the modulus bigger than the data, 2) use a Hybrid cryptosystem, or 3) least desirable is to manually break up the input into chunks that are each smaller than the modulus. If you are going to use PKCS1 padding (which is generally recommended), then the input must be not larger than n-11 bytes in length, where n is the number of bytes needed to store the RSA modulus.

Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] cipherData = cipher.doFinal(content);
Update: Are you sure you need bouncycastle for this? And why not just pass RSA as argument to Cipher.getInstance(..) ?
Update 2: Why don't you try any of these RSA encryption examples?

Related

Python to Java encryption (RSA)

I make encryption on python and try to decrypt it on Java, but always get decryption error
I have part of code for encrypt and decrypt message in JAVA encoded in RSA
For decrypt:
import java.security.*;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;
public class Decrypter
{
public static void main(String[] args)
{
try {
String encoded_data = "PueF1RC5giqmUK9U+X80SwjAjGmgfcHybjjQvWdqHSlua1rv6xr7o6OMutHBU+NRuyCJ3etTQssYOMGiWPITbEC8xr3WG9H9oRRnvel4fYARvQCqsGmf9vO9rXcaczuRKc2zy6jbutt59pKoVKNrbonIBiGN1fx+SaStBPe9Jx+aZE2hymDsa+xdmBSCyjF30R2Ljdt6LrFOiJKaDiYeF/gaej1b7D8G6p0/HBPxiHMWZhx1ZfylSvZ6+zyP0w+MJn55txR2Cln99crGtcdGeBDyBtpm3HV+u0VlW7RhgW5b+DQwjQ/liO+Ib0/ZIPP9M+3sipIwn2DKbC45o0FZHQ==";
byte[] decodeData = Base64.getDecoder().decode(encoded_data);
String publicKeyString = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxzN2+mrQRXKshq3k0r06" +
"0/FoWafOCl6fCCyuu/7SejNU95SN2LZyopA3ipamY5MeK1G1XHOhEfkPWcYcgUbz" +
"TdD166nqJGi/O+rNK9VYgfhhqD+58BCmLlNidYpV2iDmUZ9B/cvVsQi96GY5XOaK" +
"xuVZfwrDK00xcOq+aCojQEvMh+gry05uvzfSv9xK3ki5/iCMY62ReWlmrY0B19CQ" +
"47FuulmJmrxi0rv2jpKdVsMq1TrOsWDGvDgZ8ieOphOrqZjK0gvN3ktsv63kc/kP" +
"ak78lD9opNmnVKY7zMN1SdnZmloEOcDB+/W2d56+PbfeUhAHBNjgGq2QEatmdQx3" +
"VwIDAQAB";
KeyFactory kf = KeyFactory.getInstance("RSA");
byte[] encodedPb = Base64.getDecoder().decode(publicKeyString);
X509EncodedKeySpec keySpecPb = new X509EncodedKeySpec(encodedPb);
PublicKey pubKey = kf.generatePublic(keySpecPb);
Cipher cipherDecr = Cipher.getInstance("RSA");
cipherDecr.init(Cipher.DECRYPT_MODE, pubKey);
byte[] cipherDataDecr = cipherDecr.doFinal(decodeData);
String result = new String(cipherDataDecr);
System.out.println("result = "+result);
}catch (Exception e){
e.printStackTrace(System.out);
}
}
}
Unfortunately I can't make changes in this code, so all what I can is make changes in python part. This part work correctly. for check I use this code for encrypt:
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;
public class Encrypter
{
public static void main(String[] args)
{
try {
String data = "111111111222";
String privateKeyString = "here is my privat key";
byte [] encoded = Base64.getDecoder().decode(privateKeyString);
System.out.println("encoded = "+encoded);
java.security.Security.addProvider( new org.bouncycastle.jce.provider.BouncyCastleProvider());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
KeySpec ks = new PKCS8EncodedKeySpec(encoded);
RSAPrivateKey privKey = (RSAPrivateKey) keyFactory.generatePrivate(ks);
System.out.println("privKey = "+privKey);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
cipher.init(Cipher.ENCRYPT_MODE, privKey);
byte[] cipherData = cipher.doFinal(data.getBytes());
String card = Base64.getEncoder().encodeToString(cipherData);
System.out.println("data = "+card);
}catch (Exception e){
e.printStackTrace(System.out);
}
}
}
And when I use result from Java code for encrypt and put this result to decrypt Java file - all work's great. I need same encryption part, but writing with python.
Part for encrypt with python
import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
data = '111111111222'
privat_key = 'here is my privat key'
key = RSA.importKey(privat_key)
cipher = PKCS1_v1_5.new(key)
encrypted_message = str(base64.b64encode(cipher.encrypt(base64.b64decode(data))), 'utf8')
print(encrypted_message)
So, questions is how I should encrypt message for correct decryption with on Java?
I tried different libs (standard rsa, Pycrypto RSA, PKCS1_OAEP, PKCS1_v1_5) and nothing help me
P.S. I know about wrong way for use keys pair, but it is requirements of the external system
UPDATE:
Using new instance fetch me to the some result. I changed format as Maarten Bodewes said
Cipher cipherDecr = Cipher.getInstance("RSA/ECB/NoPadding");
decryption result:
����2����ٰoܬ���(�RM#�/���u*�d�{���w�b+���v�ݏ[�$�#��xJo�s��F1���X��}���1 ���������t%`�YA/��?�
�ɼej�X�T�+6Y4D��!���
I can't read it, but it's not a Exception, it is good. Try to move this way
UPDATE:
I define that Java used RSA/ECB/PKCS1Padding as default. So I should use same in python
First of all I defined that java
Cipher cipher = Cipher.getInstance("RSA");
expanded in
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
or
Cipher cipher = Cipher.getInstance("RSA/None/PKCS1PADDING");
For RSA no different what is defined in second argument (None or ECB). RSA doesn't use it.
So I need add padding to my encryption in python. Unfortunately PyCrypto hasn`t PKCS1PADDING, so i can't encrypt with this padding.
Next step I found M2Crypto lib https://gitlab.com/m2crypto/m2crypto
This fork worked for python3. just download and build it(instruction in repo)
Than I wrote this code and it works:
import M2Crypto
# read privat key
privatKey = M2Crypto.RSA.load_key('privat.key')
# encrypt plaintext using privat key
ciphertext = privatKey.private_encrypt(data.encode('utf-8'), M2Crypto.RSA.pkcs1_padding)
encrypted_message = str(base64.b64encode(ciphertext), 'utf8')
print(encrypted_message)
That's all. It works for me, and I believe, it can help u.
According to my code, Bouncy uses the padding for signature generation, so I presume that is what is different. You can perform a "raw" decrypt (modular exponentiation) and remove the padding yourself.

Android XML RSA, ERROR: java.security.InvalidKeyException: unknown key type passed to RSA

i got problem Encrypting a string using RSA.
my RSA is in XML format, it looks like that:
<RSAKeyValue><Modulus>lT8ykfyV0R8o3mJZZezLKTKJpYB90Pzvp0moLzh9CTGfgsxLKYiAl+YGaoRfQ7hVQos5UlLIONHWKPNco9kKcmL6EBJvFc8wqBnhX0p4ML2WSv1yDIRsm9XXra82WHIa3+fxK8bNUJHrucxmpr9pDRPdZGZkz+Q9s94FcOyFKbs=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>
and i'm trying to encrypt a string using this class:
import java.io.BufferedReader;
import java.io.StringReader;
import java.security.KeyPair;
import java.security.PublicKey;
import java.security.Security;
import javax.crypto.Cipher;
import org.bouncycastle.openssl.PEMReader;
import android.util.Base64;
import android.util.Log;
public class RsaEncryption {
private String publicKey;
public RsaEncryption(String publicKey)
{
this.publicKey = publicKey;
}
/*
* Function to encrypt the data.
*
*/
public String encrypt( String data ) throws Exception
{
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("RSA/None/OAEPWithSHA1AndMGF1Padding", "BC");
byte[] keyBytes = Base64.decode( this.publicKey, 0 );
PublicKey publickey = strToPublicKey(new String(keyBytes));
cipher.init( Cipher.ENCRYPT_MODE , publickey );
// Base 64 encode the encrypted data
byte[] encryptedBytes = Base64.encode( cipher.doFinal(data.getBytes()), 0 );
return new String(encryptedBytes);
}
public static PublicKey strToPublicKey(String s)
{
PublicKey pbKey = null;
try {
BufferedReader br = new BufferedReader( new StringReader(s) );
PEMReader pr = new PEMReader(br);
Object obj = pr.readObject();
if( obj instanceof PublicKey )
{
pbKey = (PublicKey) pr.readObject();
}
else if( obj instanceof KeyPair )
{
KeyPair kp = (KeyPair) pr.readObject();
pbKey = kp.getPublic();
}
pr.close();
}
catch( Exception e )
{
Log.d("CIPHER", e.getMessage() );
}
return pbKey;
}
}
as you can see i'm using bouncycastle's jar
the error that i get is:
java.security.InvalidKeyException: unknown key type passed to RSA
I'm not sure about this part
Cipher cipher = Cipher.getInstance("RSA/None/OAEPWithSHA1AndMGF1Padding", "BC");
maybe this is the problem?
if it is, what need to be there instead?
i did hours of research and still didn't find a solution...
Thanks in advance :)
Cipher cipher = Cipher.getInstance("RSA/None/OAEPWithSHA1AndMGF1Padding", "BC");
maybe this is the problem?
No it's not.
OAEPWith<digest>And<mgf>Padding
Means Optimal Asymmetric Encryption Padding scheme defined in PKCS1, where <digest> should be replaced by the message digest algorithm and <mgf> by the mask generation function. Examples: OAEPWithMD5AndMGF1Padding and OAEPWithSHA-512AndMGF1Padding.
Reference Standard Names and RFC 4055.
The problem is in your Public Key generation. As your key is in XML, and Base64 encoded:
First you need to separate modulus and exponent.
Then Base64 decode both modulus and exponent.
After decoding you will get the byte array of modulus and exponent, so you can easily prepare public key object like the following procedure:
BigInteger modBigInteger = new BigInteger(1, modulus);//modulus must be byte array
BigInteger exBigInteger = new BigInteger(1, exponent);//exp must be byte array
RSAPublicKeySpec spec = new RSAPublicKeySpec(modBigInteger, exBigInteger);
KeyFactory factory = KeyFactory.getInstance("RSA");
PublicKey publicKey = factory.generatePublic(spec);
XML is not PEM.
You need to extract the modulus and the public exponent from the XML and then generate a key using an "RSA" KeyFactory instance and a RSAPublicKeySpec.

How to fix Invalid AES key length?

I am working on a text encryption and decryption project (following Struts 2)
Whenever I enter the password and the plain text I get a Invalid AES Key Length error.
The Service Class
package com.anoncrypt.services;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class SymAES
{
private static final String ALGORITHM = "AES";
private static byte[] keyValue= new byte[] { 'T', 'h', 'i', 's', 'I', 's', 'A', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y' };
public String encode(String valueToEnc) throws Exception {
Key key = new SecretKeySpec(keyValue, ALGORITHM);
Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encValue = c.doFinal(valueToEnc.getBytes());
String encryptedValue = new BASE64Encoder().encode(encValue);
return encryptedValue;
}
public String decode(String encryptedValue) throws Exception {
Key key = new SecretKeySpec(keyValue, ALGORITHM);
Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.DECRYPT_MODE, key);
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedValue);
byte[] decValue = c.doFinal(decordedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
}
public void start(String passcode)throws Exception
{
keyValue = passcode.getBytes();
}
}
And this is the error
java.security.InvalidKeyException: Invalid AES key length: 6 bytes
com.sun.crypto.provider.AESCrypt.init(AESCrypt.java:87)
com.sun.crypto.provider.ElectronicCodeBook.init(ElectronicCodeBook.java:93)
com.sun.crypto.provider.CipherCore.init(CipherCore.java:582)
com.sun.crypto.provider.CipherCore.init(CipherCore.java:458)
com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:307)
javax.crypto.Cipher.implInit(Cipher.java:797)
javax.crypto.Cipher.chooseProvider(Cipher.java:859)
javax.crypto.Cipher.init(Cipher.java:1229)
javax.crypto.Cipher.init(Cipher.java:1166)
com.anoncrypt.services.SymAES.encode(SymAES.java:35)
com.anoncrypt.actions.SymEncrypt.execute(SymEncrypt.java:24)
Things to know in general:
Key != Password
SecretKeySpec expects a key, not a password. See below
It might be due to a policy restriction that prevents using 32 byte keys. See other answer on that
In your case
The problem is number 1: you are passing the password instead of the key.
AES only supports key sizes of 16, 24 or 32 bytes. You either need to provide exactly that amount or you derive the key from what you type in.
There are different ways to derive the key from a passphrase. Java provides a PBKDF2 implementation for such a purpose.
I used erickson's answer to paint a complete picture (only encryption, since the decryption is similar, but includes splitting the ciphertext):
SecureRandom random = new SecureRandom();
byte[] salt = new byte[16];
random.nextBytes(salt);
KeySpec spec = new PBEKeySpec("password".toCharArray(), salt, 65536, 256); // AES-256
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] key = f.generateSecret(spec).getEncoded();
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
byte[] ivBytes = new byte[16];
random.nextBytes(ivBytes);
IvParameterSpec iv = new IvParameterSpec(ivBytes);
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, keySpec, iv);
byte[] encValue = c.doFinal(valueToEnc.getBytes());
byte[] finalCiphertext = new byte[encValue.length+2*16];
System.arraycopy(ivBytes, 0, finalCiphertext, 0, 16);
System.arraycopy(salt, 0, finalCiphertext, 16, 16);
System.arraycopy(encValue, 0, finalCiphertext, 32, encValue.length);
return finalCiphertext;
Other things to keep in mind:
Always use a fully qualified Cipher name. AES is not appropriate in such a case, because different JVMs/JCE providers may use different defaults for mode of operation and padding. Use AES/CBC/PKCS5Padding. Don't use ECB mode, because it is not semantically secure.
If you don't use ECB mode then you need to send the IV along with the ciphertext. This is usually done by prefixing the IV to the ciphertext byte array. The IV is automatically created for you and you can get it through cipherInstance.getIV().
Whenever you send something, you need to be sure that it wasn't altered along the way. It is hard to implement a encryption with MAC correctly. I recommend you to use an authenticated mode like CCM or GCM.
I was facing the same issue then i made my key 16 byte and it's working properly now. Create your key exactly 16 byte. It will surely work.
You can verify the key length limit:
int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES");
System.out.println("MaxAllowedKeyLength=[" + maxKeyLen + "].");
You can use this code, this code is for AES-256-CBC or you can use it for other AES encryption. Key length error mainly comes in 256-bit encryption.
This error comes due to the encoding or charset name we pass in the SecretKeySpec. Suppose, in my case, I have a key length of 44, but I am not able to encrypt my text using this long key; Java throws me an error of invalid key length. Therefore I pass my key as a BASE64 in the function, and it converts my 44 length key in the 32 bytes, which is must for the 256-bit encryption.
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.Security;
import java.util.Base64;
public class Encrypt {
static byte [] arr = {1,2,3,4,5,6,7,8,9};
// static byte [] arr = new byte[16];
public static void main(String...args) {
try {
// System.out.println(Cipher.getMaxAllowedKeyLength("AES"));
Base64.Decoder decoder = Base64.getDecoder();
// static byte [] arr = new byte[16];
Security.setProperty("crypto.policy", "unlimited");
String key = "Your key";
// System.out.println("-------" + key);
String value = "Hey, i am adnan";
String IV = "0123456789abcdef";
// System.out.println(value);
// log.info(value);
IvParameterSpec iv = new IvParameterSpec(IV.getBytes());
// IvParameterSpec iv = new IvParameterSpec(arr);
// System.out.println(key);
SecretKeySpec skeySpec = new SecretKeySpec(decoder.decode(key), "AES");
// System.out.println(skeySpec);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// System.out.println("ddddddddd"+IV);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
// System.out.println(cipher.getIV());
byte[] encrypted = cipher.doFinal(value.getBytes());
String encryptedString = Base64.getEncoder().encodeToString(encrypted);
System.out.println("encrypted string,,,,,,,,,,,,,,,,,,,: " + encryptedString);
// vars.put("input-1",encryptedString);
// log.info("beanshell");
}catch (Exception e){
System.out.println(e.getMessage());
}
}
}

How to programmatically generate a self signed certificate?

I have a RSA public key (2048 bit) generated by a HSM, that key has been saved in a file (with a size of 256 byte) and is encoded as DER.
Is it possibile to programmatically create a self-signed certificate using JDK API (without BouncyCastle) starting from that file?
I'm stuck with the first step, because I'm trying to load the key file to create a PublicKey object:
import java.io.FileInputStream;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import org.apache.commons.io.IOUtils;
public class Crypto {
public static void main(String[] args) throws Exception {
byte[] byteArray = IOUtils.toByteArray(new FileInputStream("/tmp/pub.key"));
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(byteArray);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pub = kf.generatePublic(spec);
....
}
}
but I get this exception:
Exception in thread "main" java.security.spec.InvalidKeySpecException: Only RSAPublicKeySpec and X509EncodedKeySpec supported for RSA public keys
at sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:289)
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:184)
at java.security.KeyFactory.generatePublic(KeyFactory.java:304)
at org.alex.Crypto.main(Crypto.java:17)
Is there a way to do that?
Use X509EncodedKeySpec (which internally actually used PKCS#1 encoding for RSA keys) instead. Keep the rest of the code identical. PKCS#8 is for private keys, not public keys (because it uses the PKCS#8 internal structure required to wrap a key with another key, and wrapping public keys makes no sense).
The exception is telling you the issue! => Only RSAPublicKeySpec and X509EncodedKeySpec supported for RSA public keys
You are trying to use PKCS8EncodedKeySpec, which is not supported, create RSAPublicKeySpec or X509EncodedKeySpec class
Example
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
byte[] input = new byte[] { (byte) 0xbe, (byte) 0xef };
Cipher cipher = Cipher.getInstance("RSA/None/NoPadding", "BC");
KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(
"12345678", 16), new BigInteger("11", 16));
RSAPrivateKeySpec privKeySpec = new RSAPrivateKeySpec(new BigInteger(
"12345678", 16), new BigInteger("12345678",
16));
RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(pubKeySpec);
RSAPrivateKey privKey = (RSAPrivateKey) keyFactory.generatePrivate(privKeySpec);
cipher.init(Cipher.ENCRYPT_MODE, pubKey);

error in encrypting image with RSA

I need to encrypt an image of size 151*15 with RSA.
This is the java code to encrypt the image file
import javax.crypto.Cipher;
plaintext = time;
cipher = Cipher.getInstance('RSA');
keygen = java.security.KeyPairGenerator.getInstance('RSA');
keyPair = keygen.genKeyPair();
cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPrivate())
plaintextUnicodeVals = uint16(plaintext)
plaintextBytes = typecast(plaintextUnicodeVals, 'int8')
ciphertext = cipher.doFinal(plaintextBytes);
this is the image file to be encrypted
I got the folllowing error
Java exception occurred:
javax.crypto.IllegalBlockSizeException: Data must not be longer than 117 bytes
at com.sun.crypto.provider.RSACipher.a(DashoA13*..)
at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
please give me the hint Or procedure so that i can approach in right direction.
Thanks
You need to use AES for encrypting large data. RSA cannot encrypt data larger than key's size.
So you can encrypt an AES key with RSA, and the whole image with AES (256 bit) (i.e. generate different AES key for each image).
Also RSA is very slow and thus is not good for encrypting large data, if you want to split up an image to a large number of blocks of size 117 bytes and encrypt them one by one.
For example:
public static byte[] encrypt(byte[] data) {
try {
KeyPair keyPair = initalizeKeyPair();
final javax.crypto.Cipher rsa = javax.crypto.Cipher.getInstance("RSA");
rsa.init(javax.crypto.Cipher.ENCRYPT_MODE, keyPair.getPublic());
SecureRandom random = new SecureRandom();
final byte[] secretKey = new byte[16];
random.nextBytes(secretKey);
final javax.crypto.Cipher aes = javax.crypto.Cipher.getInstance("AES");
SecretKeySpec k = new SecretKeySpec(secretKey, "AES");
aes.init(javax.crypto.Cipher.ENCRYPT_MODE, k);
final byte[] ciphedKey = rsa.doFinal(secretKey);
final byte[] ciphedData = aes.doFinal(data);
byte[] result = new byte[256 + ciphedData.length];
System.arraycopy(ciphedKey, 0, result, 0, 256);
System.arraycopy(ciphedData, 0, result, 256, ciphedData.length);
return result;
} catch (... e) {
throw new SomeException(e);
}
}

Categories