Problema com criptografia utilizando RSA

Alguma idéia de como rodar este código corretamente (está lançando Exception com mensagem “too much data for RSA block”

 import java.math.BigInteger;
    import java.security.KeyFactory;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.RSAPrivateKeySpec;
    import java.security.spec.RSAPublicKeySpec;
    
    import javax.crypto.Cipher;
    
    /**
     * Basic RSA example.
     */
    public class TestRSA {
    
        public static void main(String[] args) throws Exception {
 
    	byte[] input = new byte[100];
    
    	Cipher cipher = Cipher.getInstance("RSA/None/NoPadding", "BC");
    	KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");
    
    	// create the keys
    
    	RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger("d46f473a2d746537de2056ae3092c451",
    		16), new BigInteger("11", 16));
    	RSAPrivateKeySpec privKeySpec = new RSAPrivateKeySpec(new BigInteger(
    		"d46f473a2d746537de2056ae3092c451", 16), new BigInteger("57791d5430d593164082036ad8b29fb1",
    		16));
    
    	RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(pubKeySpec);
    	RSAPrivateKey privKey = (RSAPrivateKey) keyFactory.generatePrivate(privKeySpec);
    
    	// encryption step
    
    	cipher.init(Cipher.ENCRYPT_MODE, pubKey);
    
    	byte[] cipherText = cipher.doFinal(input);
    
    	// decryption step
    
    	cipher.init(Cipher.DECRYPT_MODE, privKey);
    
    	byte[] plainText = cipher.doFinal(cipherText);
    
        }
    }

Você não pode criptografar um bloco maior que o tamanho da chave, usando RSA. No seu caso, o tamanho da chave é de alguns poucos bits, e você quer criptografar um bloco de 100 bytes (800 bits).

O tamanho máximo do bloco é de 16 bytes, se quiser cifrar um bloco maior terá que fazer por partes. Divida os 100 bytes em blocos de 16 e cifre-os, concatenando o resultado.
Na hora do decrypt terá que fazer a mesma coisa :lol:

tentei faze um loop…

byte[] cipherText = new byte[input.length];
 for (int i = 0; i < input.length; i++) {
     byte[] singleByteArray = new byte[] { input[i] };
     cipherText[i] = cipher.doFinal(singleByteArray)[0];
 }

…mas não deu certo (mesmo com array de bytes de 0x03) o cipherText se torna um array de zeros… :?

A criptografia RSA não é destinada a ser usada para criptografar coisas, apenas chaves.

Não tente criptografar 100 bytes se sua chave RSA tiver menos de 800 bits.

E essa história de criptografar por blocos, no caso da RSA, não é adequado porque isso expõe uma vulnerabilidade no algoritmo quando uma mesma chave RSA é usada para criptografar vários blocos. Nunca se usa apenas a RSA sozinha; ela deve ser sempre combinada com um algoritmo simétrico como o AES ou o Triple-DES.

O que se costuma fazer é criar uma chave AES (por exemplo), que tem sempre 128/192/256 bits, e criptografar essa chave usando RSA.

Então você criptografa o seu texto original (aquele trambolho que tem 100 ou mais bytes) com essa chave AES, e criptografa a chave AES com a chave RSA.

[quote=entanglement]A criptografia RSA não é destinada a ser usada para criptografar coisas, apenas chaves.

Não tente criptografar 100 bytes se sua chave RSA tiver menos de 800 bits.

E essa história de criptografar por blocos, no caso da RSA, não é adequado porque isso expõe uma vulnerabilidade no algoritmo quando uma mesma chave RSA é usada para criptografar vários blocos. Nunca se usa apenas a RSA sozinha; ela deve ser sempre combinada com um algoritmo simétrico como o AES ou o Triple-DES.

O que se costuma fazer é criar uma chave AES (por exemplo), que tem sempre 128/192/256 bits, e criptografar essa chave usando RSA.

Então você criptografa o seu texto original (aquele trambolho que tem 100 ou mais bytes) com essa chave AES, e criptografa a chave AES com a chave RSA.
[/quote]

É o que vou fazer, estou usando AES e vou criptografar a cheve usando RSA. Mas o número de chaves vai variar, posso criptografar apenas 1 chave por vez? E se for o caso, o tamanho das chaves AES é constante? A aplicação nunca vai falhar por estourar o tamanho do bloco RSA?

  1. Eu recomendo criptografar uma chave de cada vez.
  2. O tamanho de uma chave AES pode ser: 128, 192 ou 256 bits. É só questão de escolher (e lembrar que o Java, se você não alterar um arquivo na JRE, só aceita chaves de 128 bits no máximo. Veja em:

https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/ViewProductDetail-Start?ProductRef=jce_policy-6-oth-JPR@CDS-CDS_Developer

( Java™ Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6 )