【问题标题】:org.bouncycastle.crypto.InvalidCipherTextException: block incorrectorg.bouncycastle.crypto.InvalidCipherTextException:块不正确
【发布时间】:2017-03-04 15:01:41
【问题描述】:

我必须使用 bouncycastle api 对文件进行编码,加密效果很好,但是在第一次迭代的解密中出现错误 org.bouncycastle.crypto.InvalidCipherTextException: block不正确出现

这是为了加密及其工作

public void cifrado() throws IOException, InvalidCipherTextException{
    RSAEngine motor = new RSAEngine();
    PKCS1Encoding padding = new PKCS1Encoding(motor);

    BufferedReader fClave = new BufferedReader(new FileReader(clave));

    File Entrada = new File(ficheroEntrada);
    BufferedInputStream bInEntrada = new BufferedInputStream(new FileInputStream(Entrada));

    File Destino = new File(ficheroSalida);
    BufferedOutputStream bOutDestino = new BufferedOutputStream(new FileOutputStream(Destino));

    //Metemos en un String la clave leida del fichero con readline en la que tendremos modulo, caracter CRLF y exponente
    String modulo = fClave.readLine();
    String exponente = fClave.readLine();
    //Decodificamos el Hexadecimal leido 
    byte[] bModulo = Hex.decode(modulo);
    byte[] bExponente = Hex.decode(exponente);

    //Ahora con el modulo y exponente ya podemos utilizar el RSAKeyParameter e inicializar el motor de padding en modo cifrado
    padding.init(true, new RSAKeyParameters(false,new BigInteger(bModulo),new BigInteger(bExponente))); 
    System.out.println(padding.getInputBlockSize() + "  " + padding.getOutputBlockSize());

    //Leemos de 117 bytes en 117 bytes que es lo maximo que admite los bloques de entrada
    byte[] array117 = new byte[117];
    byte[] salida;
    long longitudFichero = Entrada.length();
    System.out.println(longitudFichero);
    long contador = longitudFichero;
    while(contador>0){
        bInEntrada.read(array117, 0, array117.length);
        salida= padding.processBlock(array117, 0, array117.length);
        System.out.println(salida.length);
        bOutDestino.write(salida, 0, salida.length);
        contador = ((contador>0)?contador-=117:contador);
    }
        bInEntrada.close();
        bOutDestino.close();
        fClave.close();
}

这是为了解密

public void descifrado() throws IOException, InvalidCipherTextException{
    RSAEngine motor = new RSAEngine();
    PKCS1Encoding padding = new PKCS1Encoding(motor);

    BufferedReader fClave = new BufferedReader(new FileReader(clave));

    File Entrada = new File(ficheroEntrada);
    BufferedInputStream bInCifrado = new BufferedInputStream(new FileInputStream(Entrada));

    File Destino = new File(ficheroSalida);
    BufferedOutputStream bOutDescifrado = new BufferedOutputStream(new FileOutputStream(Destino));

    //Metemos en un String la clave leida del fichero con readline en la que tendremos modulo, caracter CRLF y exponente
    String modulo = fClave.readLine();
    String exponente = fClave.readLine();
    //Decodificamos el Hexadecimal leido 
    byte[] bModulo = Hex.decode(modulo);
    byte[] bExponente = Hex.decode(exponente);
    System.out.println(bModulo.length + "  " +  bExponente.length);
    //Ahora con el modulo y exponente ya podemos utilizar el RSAKeyParameter e inicializar el motor de padding en modo descifrado
    padding.init(false, new RSAKeyParameters(false,new BigInteger(bModulo),new BigInteger(bExponente)));    
    System.out.println(padding.getInputBlockSize() + "  " + padding.getOutputBlockSize());

    //Leemos de 128 bytes en 128 bytes que es lo maximo que admite los bloques de entrada cuando decodificamos
    byte[] array128 = new byte[128];

    long longitudFichero = Entrada.length();
    long contador = longitudFichero;
    System.out.println(longitudFichero);
    while(contador!=0){
        bInCifrado.read(array128, 0, array128.length);
        byte[] salida= padding.processBlock(array128, 0, array128.length);
        System.out.println(salida.length);
        /*for(byte i: salida){
            System.out.println(i);
        }*/
        bOutDescifrado.write(salida, 0, salida.length);
        contador -=128;
    }
        bInCifrado.close();
        bOutDescifrado.close();
        fClave.close();
}

【问题讨论】:

  • 加密和解密总是同时进行的。请edit您的代码包含加密代码以及示例输入和输出。另外,异常来自哪一行?
  • 嗨,我刚刚上传了加密,谢谢
  • 看起来您使用相同的输入和输出文件进行加密和解密。但是,对于解密,输入文件应该是加密的输出文件。事实上,解密函数看起来几乎是加密函数的翻版。但解密应该使用 rsa 解密指数。
  • 别担心,我完全理解你,但文件看起来一样但不一样,因为当我调用构造函数时,我将文件名传递给它。和解密指数是什么意思?。
  • 好吧,在这种情况下,您需要在clave 中拥有解密指数,并将RSAKeyParameters 的第一个参数设置为true

标签: java cryptography rsa bouncycastle pkcs#1


【解决方案1】:

我只是修复了重复的最后一个块,解决方案是在 cifrado 方法中,我必须检查最后一个块的输入大小是否正确

while(contador>0){
        if(contador>0 && contador<117){
            byte[] ultimo = new byte[(int) contador];
            bInEntrada.read(ultimo, 0, ultimo.length);
            salida= padding.processBlock(ultimo, 0, ultimo.length);
            System.out.println(salida.length);
            bOutDestino.write(salida, 0, salida.length);
            contador=0;

        }else{
            bInEntrada.read(array117, 0, array117.length);
            salida= padding.processBlock(array117, 0, array117.length);
            System.out.println(salida.length);
            bOutDestino.write(salida, 0, salida.length);
            contador = ((contador>0)?contador-=117:contador);
        }
    }

【讨论】:

    猜你喜欢
    • 2011-05-18
    • 1970-01-01
    • 2019-02-14
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    • 2022-08-20
    • 2021-11-12
    • 2016-10-04
    相关资源
    最近更新 更多