Java、rsa加密
Java, rsa encryption
所以我有一个字节数组,我想使用 rsa 加密这个数组,但我也想像这样保持第一个字节不变:
//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
我应该使用哪种 doFinal 方法?
@编辑
为什么这不起作用?
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();
}
输出为:
START!
1
2
3
4
111
-44
120
103
java.lang.ArrayIndexOutOfBoundsException: 3
您应该使用 byte[] doFinal(byte[] input, int inputOffset, int inputLen)
指定 1
作为输入偏移量和数组的长度作为输入长度。
你的情况:doFinal(byteArray, 1, byteArray.length)
这与 RSA 无关,这只是基本的 Java 编程错误。 pack2[0]
到pack2[pack2.length-1]
包含加密pack[1]
到pack[pack.length-1]
的结果。因此,为了成功解密,您必须提供 pack2[0]
到 pack2[pack2.length-1]
。由于您为解密器提供 pack2
从 pack2[1]
开始,您的代码应该抛出解密错误异常,而不是您报告的异常。因此,我还必须得出结论,您提供的代码和您提供的输出不一致。
如果你想将 pack 的第一个字节复制到 pack2,你必须自己做,也许需要 Arrays.copy*() 方法之一的帮助 and/or System.arraycopy ().
我已经稍微更新了您的代码。查找我插入的评论。
本质上,当您加密时,RSA returns 一个数据块 (cipher-text) 比您的数据 (plain-text) 大得多。这是设计使然。在您的情况下,由于您使用 512 位作为密钥长度,因此您可以期望通过加密 plain-text 获得 512 位(64 字节)的输出块。要解密 cipher-text,您 必须 拥有 cipher-text 的整个块来执行解密。
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();
}
所以我有一个字节数组,我想使用 rsa 加密这个数组,但我也想像这样保持第一个字节不变:
//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
我应该使用哪种 doFinal 方法?
@编辑 为什么这不起作用?
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();
}
输出为:
START! 1 2 3 4 111 -44 120 103 java.lang.ArrayIndexOutOfBoundsException: 3
您应该使用 byte[] doFinal(byte[] input, int inputOffset, int inputLen)
指定 1
作为输入偏移量和数组的长度作为输入长度。
你的情况:doFinal(byteArray, 1, byteArray.length)
这与 RSA 无关,这只是基本的 Java 编程错误。 pack2[0]
到pack2[pack2.length-1]
包含加密pack[1]
到pack[pack.length-1]
的结果。因此,为了成功解密,您必须提供 pack2[0]
到 pack2[pack2.length-1]
。由于您为解密器提供 pack2
从 pack2[1]
开始,您的代码应该抛出解密错误异常,而不是您报告的异常。因此,我还必须得出结论,您提供的代码和您提供的输出不一致。
如果你想将 pack 的第一个字节复制到 pack2,你必须自己做,也许需要 Arrays.copy*() 方法之一的帮助 and/or System.arraycopy ().
我已经稍微更新了您的代码。查找我插入的评论。
本质上,当您加密时,RSA returns 一个数据块 (cipher-text) 比您的数据 (plain-text) 大得多。这是设计使然。在您的情况下,由于您使用 512 位作为密钥长度,因此您可以期望通过加密 plain-text 获得 512 位(64 字节)的输出块。要解密 cipher-text,您 必须 拥有 cipher-text 的整个块来执行解密。
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();
}