문제

I have a problem with RSA cryptography when messages are too long.

MyCipher:

public static byte[] encrypt(byte[] dataToEncrypt, PublicKey pubk){
    try{
    System.out.println("in encrypt");
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(Cipher.ENCRYPT_MODE, pubk);

    byte[] encrypted = new byte[dataToEncrypt.length];
    System.out.println("Imagebyte length: " + dataToEncrypt.length);
    byte[] temp = new byte[53];
    byte[] temp2 = null;
    int x, y, z = 0;
    int repeats = dataToEncrypt.length / 53;
    System.out.println("Iterations: " + repeats);
    for (z = 0; z < repeats; z++) {
        System.out.println("Iteration number: " + z);
        int offset = z * 53;
        for (x = 0; x < 53; x++) {
            temp[x] = (byte) dataToEncrypt[offset + x];
        }
        temp2 = cipher.doFinal(temp);
        for (y = 0; y < 53; y++) {
            encrypted[offset + y] = (byte) temp2[y];
        }
        temp2 = null;
    }
    return encrypted;
    }catch(Exception e){
        return null;
    }
}


public static byte[] decrypt(byte[] bytesIn, PrivateKey prvk){
    try {
        System.out.println("in decrypt");
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        System.out.println("read out" + prvk);
        cipher.init(Cipher.DECRYPT_MODE, prvk);
        byte[] decrypted = new byte[bytesIn.length];
        System.out.println("Imagebyte length: " + bytesIn.length);
        byte[] temp = new byte[53];
        byte[] temp2 = null;
        int x, y, z = 0;
        int repeats = bytesIn.length / 53;
        System.out.println("Iterations: " + repeats);

        for (z = 0; z < repeats; z++) {
            System.out.println("Iteration number: " + z);
            int offset = z * 53;
            for (x = 0; x < 53; x++) {
                temp[x] = (byte) bytesIn[offset + x];
            }
            temp2 = cipher.doFinal(temp);
            for (y = 0; y < 53; y++) {
                decrypted[offset + y] = (byte) temp2[y];
            }
            temp2 = null;
        }
        return decrypted;
    } catch (Exception e) {
        System.err.println(e);
        return null;
    }
}

Main:

 public static void main(String args[]) { 
    MsgAtoB_1 msg= new MsgAtoB_1(new BigInteger(String.valueOf(System.currentTimeMillis())), "login");
    byte [] tab = MySerializer.serialize(msg);
    KeyPair key = Keys.generateKeyPair();
    byte [] crypt = MyCipher.encrypt(tab, key.getPublic());
    byte [] decrypt = MyCipher.decrypt(crypt,key.getPrivate() );
    if(tab.equals(decrypt)) System.out.println("yes it's work ");
    else System.out.println("KOOOOOOOOOOO");          
}

Output:

run:
in encrypt
Imagebyte length: 319
Iterations: 6
Iteration number: 0
Iteration number: 1
Iteration number: 2
Iteration number: 3
Iteration number: 4
Iteration number: 5
in decrypt
read outsun.security.rsa.RSAPrivateCrtKeyImpl@fff5bef2
Imagebyte length: 319
Iterations: 6
Iteration number: 0
javax.crypto.BadPaddingException: Data must start with zero
KOOOOOOOOOOO
도움이 되었습니까?

해결책

Hi the solution was here : Encrypting and decrypting large data using Java and RSA Encrypting and decrypting large data using Java and RSA

다른 팁

You specified the padding mode, meaning that cipher pads the input data and returns an array of different (greater) length.

In particular, the following line in both your methods receives the data from the cipher but does not use the length of the returned data in any way:

temp2 = cipher.doFinal(temp);

When encrypting, you are basically truncating every "block" to 53 bytes (how and way you have choose that number is another question). When decrypting, you are passing this truncated data to the cipher which predictably causes BadPaddingException.

It is possible to "fix" your code by collecting individual encrypted chunks in some kind of resizing array (ByteArrayOutputStream for example) and storing the length of each chunk to be able to to split the stream when decoding, but you will end with poorly implemented "kind of stream" cipher.

You should consider using another cipher (for example, AES) and another cipher mode (for example, CTR) which provide streaming capabilities out of the box.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top