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]。由于您为解密器提供 pack2pack2[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();
}