简体   繁体   中英

RSA encrypt with BouncyCastle API

I have a problem when I want to encrypt a file using RSA with BouncyCastle API in Java. The problem is the following: in the code below, the line in which I create an object of RSAKeyParameters,its constructor asks me three parameters:
1. If We want to cipher with public or private key.
2. A BigInteger with the modulus of the key.
3. A BigInteger with the exponent of the key.

The first parameter that my method receives is the file where the key is contained. So in the RSAKeyParameter's constructor, how can I pass it a BigInteger that is the modulus and exponent?, how can I get the modulus and the exponent from the file?

PD: The file that contains the key has a CR and LF, that's why there are two readLine().

void cifrar_asimetrica(String fichClave, String archivoClaro, String result, boolean conPrivada){

    byte[] modulo;
    byte[] exponente;

    try(
        BufferedReader lectorClave = new BufferedReader (new FileReader(fichClave));
        BufferedInputStream lectorFichero = new BufferedInputStream(new FileInputStream(archivoClaro));
        BufferedOutputStream fsalida = new BufferedOutputStream(new FileOutputStream(result))){

        modulo = Hex.decode(lectorClave.readLine()); 
        exponente = Hex.decode(lectorClave.readLine());


        RSAEngine cifrador = new RSAEngine();
        CipherParameters parametro = new RSAKeyParameters(conPrivada, new BigInteger(modulo.toString()), new BigInteger(exponente.toString()));

        cifrador.init(true,parametro); // vamos a cifrar

        byte[] datosLeidos = new byte[cifrador.getOutputBlockSize()];
        byte[] datosCifrados = new byte[cifrador.getOutputBlockSize()];
        int leidos = 0;
        //NO SE SI ES GETINPUTBLOCKSIZE O OUTPUT
        leidos = lectorFichero.read(datosLeidos, 0, cifrador.getOutputBlockSize());

        while(leidos > 0){
            datosCifrados = cifrador.processBlock(datosLeidos, 0, cifrador.getOutputBlockSize());
            fsalida.write(datosCifrados, 0, datosCifrados.length);
            leidos = lectorFichero.read(datosLeidos, 0, cifrador.getOutputBlockSize());
        }

    }catch(Exception e){
        e.printStackTrace();
    }
}

If your byte arrays, converted from hex in the file, are big-endian as is conventional, to convert a positive big-endian byte array to BigInteger look at the javadoc for BigInteger for the constructor that takes an int sign for positive and a big-endian byte array for magnitude.

'Textbook' (unpadded) RSA is insecure; see crypto.SX security.SX and wikipedia. Using RSA for data larger than one block the way you've coded it will semi-randomly fail, and if you correct that, what amounts to ECB mode is inefficient and insecure; see crypto.SX security.SX and wikipedia. Using an unauthenticated public key is usually insecure.

If you are doing this for fun because it makes you feel like a "l33t hack5r" or Bond supervillain, and don't care about actual securty, this is fine. If you need or want actual security, drop this and use programs written by people who know what they are doing, and/or search 'don't roll your own crypto'.

You're currently using toString on a byte array. This will only return a representative of the object reference, which has little to do with the value within the array.

Instead you can use the BigInteger constructor that takes a string and radix , using 16 as radix. Do make sure that you don't have any spurious or invalid characters in the hexadecimal representation though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM