我有javax.crypto.BadPaddingException:RSA Cryptography

时间:2014-04-28 15:02:27

标签: java encryption rsa

当邮件太长时,我遇到RSA加密问题。

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;
    }
}

主要

 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");          
}

输出:

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

2 个答案:

答案 0 :(得分:0)

您指定了填充模式,这意味着密码填充输入数据并返回不同(更大)长度的数组。

特别是,两个方法中的以下行都接收来自密码的数据,但不以任何方式使用返回数据的长度:

temp2 = cipher.doFinal(temp);

加密时,基本上将每个“块”截断为53个字节(如何以及如何选择该数字是另一个问题)。解密时,您将此截断的数据传递给密码,该密码可预测导致BadPaddingException

可以通过在某种调整大小数组(例如ByteArrayOutputStream)中收集单个加密块来“修复”您的代码,并存储每个块的长度,以便在解码时能够拆分流,但是你会以糟糕的“流式”密码结束。

您应该考虑使用另一种密码(例如AES)和另一种密码模式(例如CTR)来提供开箱即用的流媒体功能。

答案 1 :(得分:0)

解决方案就在这里:使用Java和RSA加密和解密大数据 Encrypting and decrypting large data using Java and RSA