Pregunta

Hola esta es la misma pregunta, que se hizo hace dos años: Java / JCE: Decodificación “largo” mensaje cifrado con RSA

Yo tenía una gran matriz de bytes y RSA par de claves, iniciado por valor de 1.024. El uso de encriptación RSA y el tamaño especificado de la clave es requisito fuerte, no puedo cambiarlo. Así que no puedo utilizar el cifrado simétrico con clave simétrica de cifrado asimétrico. No puedo usar ninguna otra tecla. Tenía una matriz de bytes y la necesidad de cifrado matriz de bytes que ser devuelto. Me pregunto si hay alguna herramienta lista, que puede manejar con este problema?

Lo siento por una pregunta tan poco profesional, pero realmente necesito una ayuda.

¿Fue útil?

Solución

Como se ha dicho, su pregunta tiene una sola respuesta, y eso es "no". cifrado RSA es un algoritmo que cifra los mensajes hasta un tamaño dado, que depende del tamaño de la clave; con una clave RSA de 1024 bits, y RSA como la norma describe , el tamaño máximo es de 117 bytes, no más. No hay manera de cifrar un mensaje más grande con RSA solo, y eso es una certeza matemática definida.

Si realmente necesita para procesar los mensajes más largos, entonces necesariamente tiene que añadir algo más. En ese caso, por favor, por favor , no tratan de hacer nada de fantasía de su propia invención con un poco de división oh-tan-inteligente de datos en pequeños bloques y similares. Esto nos lleva a la trayectoria del Destino. Es posible producir algo que aparece para compilar y ejecutar, pero que será siempre débil de alguna manera, al igual que casi todas las otras variaciones de fabricación casera en la criptografía. Eso es porque la seguridad no se pueden probar:. No "no funciona" es un caso de "obras" o

La ruta bien pisado de cifrado asimétrico va así:

  1. selecciona una secuencia aleatoria de bytes de cierta longitud apropiada, por ejemplo 128 bits (que es 16 bytes). Digamos que es K .
  2. Cifra K con la clave pública RSA; esta rendimientos E .
  3. cifrar el mensaje con K usando un algoritmo de cifrado simétrico ("AES/CBC/PKCS5Padding"). Dado que esta es una clave de una sola vez, se puede utilizar un todo-ceros IV. Esto produce un montón de bytes, llamémoslo F .
  4. El mensaje cifrado es entonces la concatenación de E y F .

El descifrado procede en el orden inverso: la clave privada RSA se utiliza para recuperar K de E , entonces K se utiliza para descifrar < em> F en el mensaje original. La clave K nunca se almacena en cualquier lugar, y un duplicado de la llave K se genera cada vez (incluso si cifra el mismo mensaje dos veces). Eso es importante, no cambian a menos que entienda lo que está haciendo (y si lo hace, entonces usted ya sabe que).

Teniendo en cuenta lo que usted afirma acerca de su problema, Tienes para hacer otra cosa que un "simple RSA". El procedimiento describo más arriba es de lo mejor "algo más" que se podía llegar a, seguridad inteligente.

Montaje de algunos elementos criptográficos en un protocolo de este tipo es un proceso plagado de trampas lo que puede tener mejor suerte usando una biblioteca de formato y soporte ya definido. Dos formatos comunes para el cifrado asimétrico son CMS y OpenPGP . Una biblioteca que apoya tanto y tiene buena reputación es Castillo Hinchable .

Otros consejos

Si lo hace necesidad de cifrar / descifrar largas cadenas utilizando RSA, entonces se puede romper los bytes en que "trozos" más pequeños y procesar cada trozo de bytes a través de un sistema de cifrado a la vez, mientras que el almacenamiento de los resultados en un ByteBuffer.

Cifrado:

byte[] encData = null;
try {

    // create public key
    X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(key);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PublicKey pk = kf.generatePublic(publicKeySpec);

    Cipher pkCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    pkCipher.init(Cipher.ENCRYPT_MODE, pk);

    int chunkSize = 117; // 1024 / 8 - 11(padding) = 117
    int encSize = (int) (Math.ceil(data.length/117.0)*128);
    int idx = 0;
    ByteBuffer buf = ByteBuffer.allocate(encSize);
    while (idx < data.length) {
        int len = Math.min(data.length-idx, chunkSize);
        byte[] encChunk = pkCipher.doFinal(data, idx, len);
        buf.put(encChunk);
        idx += len;
    }

    // fully encrypted data     
    encData = buf.array();
} catch (Exception e) {
    e.printStackTrace();

Descifrado

Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
rsaCipher.init(Cipher.DECRYPT_MODE, rsaPk);

int chunkSize = 128;
int idx = 0;
ByteBuffer buf = ByteBuffer.allocate(data.length);
while(idx < data.length) {
    int len = Math.min(data.length-idx, chunkSize);
    byte[] chunk = rsaCipher.doFinal(data, idx, len);
    buf.put(chunk);
    idx += len;
}

// fully decrypted data
byte[] decryptedData = buf.array();
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top