Reputation: 449
So I have a byte array and I want to encrypt this array using rsa, but also I want to leave first byte untouched like this:
//Before encryption:
byteArray[0] = 1;
byteArray[1] = 0;
byteArray[2] = 1;
//After encryption:
byteArray[0] = 1; //untouched
byteArray[1] = -127; //encrypted
byteArray[2] = 230; //encrypted
Which method of doFinal I should use?
@edit Why this isn't working?
try
{
byte[] pack = new byte[4];
byte[] pack2;
byte[] pack3;
pack[0] = 1;
pack[1] = 2;
pack[2] = 3;
pack[3] = 4;
System.out.println("START!");
for(int i = 0; i < 4; i++)
{
System.out.println(pack[i]);
}
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(512);
KeyPair keyPair = keyPairGenerator.genKeyPair();
Cipher cip = Cipher.getInstance("RSA");
cip.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
pack2 = cip.doFinal(pack, 1, pack.length-1);
for(int i = 0; i < 4; i++)
{
System.out.println(pack2[i]);
}
Cipher cip2 = Cipher.getInstance("RSA");
cip2.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
pack3 = cip2.doFinal(pack2, 1, pack2.length-1);
for(int i = 0; i < 4; i++)
{
System.out.println(pack3[i]);
}
System.out.println("END!");
}
catch(Exception e)
{
e.printStackTrace();
}
and output is:
START! 1 2 3 4 111 -44 120 103 java.lang.ArrayIndexOutOfBoundsException: 3
Upvotes: 1
Views: 884
Reputation: 9767
I've updated your code a little. Look for the comments I've inserted.
Essentially, RSA returns a block of data (cipher-text) when you encrypt that is significantly larger than your data (plain-text). This is by design. In your case, since you are using 512-bits for your key length, you can expect a 512-bit (64-byte) output block from enciphering the plain-text. To decipher the cipher-text you MUST have the entire block of cipher-text to perform a decrypt.
try
{
byte[] pack = new byte[4];
byte[] pack2;
byte[] pack3;
pack[0] = 1;
pack[1] = 2;
pack[2] = 3;
pack[3] = 4;
System.out.println("START!");
System.out.println("pack");
for(int i = 0; i < 4; i++)
{
System.out.println(pack[i]);
}
System.out.println("");
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(512);
KeyPair keyPair = keyPairGenerator.genKeyPair();
Cipher cip = Cipher.getInstance("RSA");
cip.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
// I think you said you wanted the last 3 bytes encrypted
// vvvvvvvvvvvvvvvv
pack2 = cip.doFinal(pack, 1, pack.length-1);
System.out.println("pack2");
for(int i = 0; i < 4; i++)
{
System.out.println(pack2[i]);
}
System.out.println("");
Cipher cip2 = Cipher.getInstance("RSA");
cip2.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
byte[] pack3Tmp= cip2.doFinal(pack2, 0, pack2.length);
pack3= new byte[pack.length];
// Copy over the first byte you had mentioned to be
// unecrypted
pack3[0]= pack[0];
// Use System.arraycopy
// Source is pack3Tmp
// | Starting offset is 0
// | | Destination is pack3
// | | | Staring offset in pack3 is 1
// | | | | Copy all of pack3Tmp
// | | | | |
// v v v v v
System.arraycopy(pack3Tmp, 0, pack3, 1, pack3Tmp.length);
System.out.println("pack3");
for(int i = 0; i < 4; i++)
{
System.out.println(pack3[i]);
}
System.out.println("");
System.out.println("END!");
}
catch(Exception e)
{
e.printStackTrace();
}
Upvotes: 2
Reputation: 41958
This has nothing to do with RSA, it's just basic Java programming mistakes. pack2[0]
through pack2[pack2.length-1]
contain the result of encrypting pack[1]
through pack[pack.length-1]
. Thus, in order to decrypt successfully, you must supply pack2[0]
through pack2[pack2.length-1]
. Since you supply the decryptor with pack2
starting pack2[1]
your code should throw a decryption error exception, not the exception you are reporting. Therefore I have to also conclude that code you provided and the output you provided don't go together.
If you want to copy the first byte of pack to pack2 you have to do that yourself, perhaps with the assistance of one of Arrays.copy*() methods and/or System.arraycopy().
Upvotes: 2
Reputation: 10270
You should use byte[] doFinal(byte[] input, int inputOffset, int inputLen)
specifying 1
as the input offset and the length of the array as the input length.
In your case: doFinal(byteArray, 1, byteArray.length)
Upvotes: 0