RSA Cifrado con clave pública (en Java)

Estoy buscando un Java de ejemplo de cómo hacer de Cifrado RSA con una dado la clave pública (lo tengo en formato base64, parece que es de 1024 bits de longitud).

A continuación es mi código, pero tengo InvalidKeySpec excepción.

String publicKey = "AJOnAeTfeU4K+do5QdBM2BQUhfrRI2rYf/Gk4a3jZJB2ewekgq2VgLNislBdql/glA39w0NjXZyTg0mW917JdUlHqKoQ9765pJc4aTjvX+3IxdFhteyO2jE3vKX1GgA3i3n6+sMBAJiT3ax57i68mbT+KAeP1AX9199aj2W4JZeP";
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] res = new Base64Encoder().decode(publicKey.getBytes());
X509EncodedKeySpec KeySpec = new X509EncodedKeySpec(res);
RSAPublicKey pubKey = (RSAPublicKey)keyFactory.generatePublic(KeySpec);

//here the exception occurs..

Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] cipherData = cipher.doFinal(input.getBytes());
return cipherData;

Por favor, dame la muestra,

  • ¿Cómo fue la clave pública creado?

4 Kommentare

  1. 42

    He aquí cómo me las arreglo para cifrar una cadena con sólo una clave pública RSA.

    Primera guardar la clave pública en PEM-formato para el nombre de archivo de clave pública.pem

    -----BEGIN PUBLIC KEY-----
    AJOnAeTfeU4K+do5QdBM2BQUhfrRI2rYf/Gk4...
    -----END PUBLIC KEY-----

    Encontrar la clave pública RSA módulo

    $ openssl rsa -pubin -in pubkey.pem -modulus -noout
    Modulus=F56D...

    Encontrar la clave pública RSA Exponente

    $ openssl rsa -pubin -in pubkey.pem -text -noout
    ...
    Exponent: 65537 (0x10001)

    Y luego insertar en el código siguiente.

    BigInteger modulus = new BigInteger("F56D...", 16);
    BigInteger pubExp = new BigInteger("010001", 16);
    
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(modulus, pubExp);
    RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(pubKeySpec);
    
    Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");
    cipher.init(Cipher.ENCRYPT_MODE, key);
    
    byte[] cipherData = cipher.doFinal(text.getBytes());
    • Pregunta: si tengo el módulo y el exponente, la clave pública de generar cada vez debe ser el mismo, ¿verdad?
    • Sí, pero ellos fueron generados a partir de la clave pública, que es, además, público. Se supone que debe ser público para que todo el mundo puede crear el cifrado de datos y sólo el poseedor de la clave privada puede leer.
    • Buena respuesta para aquellos (como yo) que solo trabajo basado en archivos generados. Gracias por este.
    • Hola, text.getBytes() es el archivo de almacén de la cadena, a la derecha? @nevcx
    • Sí, los datos se cifran y se almacenan en la variable cipherData. docs.oracle.com/javase/7/docs/api/javax/crypto/…
  2. 14

    Su «clave» no es válido clave pública. Es una cadena Base64 que, cuando se decodifica, los rendimientos de una secuencia de 129 bytes, siendo la primera, 0x00, seguido por 0x93. Este no es un formato válido para una clave pública RSA, pero sospechosamente se parece a big-endian firmado la codificación de una resolución de 1024 bits con signo (es decir, el tipo de codificación devuelto por BigInteger.toByteArray() y se utiliza en ASN.1 «ENTERO» valores). Una clave pública RSA nominalmente consta de dos enteros, uno es el el módulo de y el otro el público exponente. Un típico RSA módulo tiene una longitud de 1024 bits, por lo que las posibilidades son que usted tiene aquí el módulo. Usted todavía necesita el público exponente para completar la clave.

    X509EncodedKeySpec espera que el DER codificación de un ASN.1 estructura que identifica el algoritmo como RSA, y contiene un anidada codificado estructura que en sí contiene dos enteros para la clave pública RSA. El montaje de una estructura de este tipo a mano puede resultar difícil (es factible, pero requiere una comprensión en profundidad de la ASN.1). Un método más sencillo sería utilizar RSAPublicKeySpec:

    String modulusBase64 = "..."; //your Base64 string here
    BigInteger modulus = new BigInteger(1,
            new Base64Encoder.decode(modulusBase64.getBytes("UTF-8")));
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    RSAPublicKeySpec ks = new RSAPublicKeySpec(modulus, pubExp);
    RSAPublicKey pubKey = (RSAPublicKey)keyFactory.generatePublic(KeySpec);

    En el anterior, «pubExp» debe ser un BigInteger que contiene el público exponente, que no se dan. 3 y 65537 son los valores tradicionales para el público exponente, pero otras son posibles, y que no dan suficiente información para discriminar entre lo público exponentes (es decir, el código aparecerá para el trabajo, incluso si usted no usa la de la derecha). Básicamente, usted sólo tiene la mitad de la clave pública; usted debe preguntar a quien te dio de que la mitad de enviar la otra mitad también.

    Nota: String.getBytes() utiliza la plataforma de codificación predeterminada, que no es siempre el mismo. Si usted insiste en convertir una cadena a una secuencia de bytes, se debe utilizar un explícito nombre de codificación de caracteres, tales como "UTF-8", de lo contrario puede tener problemas si su código siempre se ejecuta en, digamos, un ruso o Chino sistema. También, no sé de donde su Base64Encoder clase viene (no es parte de la norma API de Java), pero es probable que también podría trabajar directamente sobre un String, o un StringReader, haciendo que el paso de la conversión innecesaria.

    • cómo hacer u obtener el módulo y pubExp de una clave ssh?
    • Estoy usando java 7 y no puedo encontrar Base64Encoder clase, donde puedo conseguir esta dependencia ?
  3. 0

    Es su clave pública realmente X509 codificado? Si no, entonces un sin codificar Keyspec debe ayudar.

  4. 0

    Su clave pública no se ve como una codificación Base64 1024 bits. Una resolución de 1024 bits valor requeriría 172 personajes (el último de un relleno =) y aquí tenemos 175 caracteres.

    Para una prueba, reemplace el últimos cuatro caracteres en su Cadena con una sola = y probar si esto elimina la excepción. Esto no solucionará el problema, pero se puede apuntar en la dirección correcta.

    • Hice un pequeño error en el código pasado por aquí (ahora está corregido). La clave pública realmente es exactamente 172 caracteres.
    • pero la última char aún no es '=' – 172 char Base64 sin relleno de bytes hace 172/(4/3)*8 =1032 bits.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea