2012-05-09 54 views
8

tengo que sustituir el cifrar y descifrar paso de Unix a código Java con la rsaprivatekey.pem y rsapublickey.pem claves generadas con opensslCómo cifrar descifrar con claves RSA en java

que generan las claves

openssl genrsa -out /tmp/rsaprivatekey.pem -des3 1024 
openssl rsa -in /tmp/rsaprivatekey.pem -pubout -out /tmp/rsapublickey.pem 

i utilizar las teclas de UNIX (que necesito hacerlo en java)

echo "Text to encript"| openssl rsautl -encrypt -inkey /tmp/rsapublickey.pem -pubin -out out.enc 
openssl rsautl -decrypt -inkey /tmp/rsaprivatekey.pem -in out.enc 

Este fue mi intento de hacerlo

public static void main(String[] args) { 


    Base64 base64 = new Base64(); 

    String TextStream = "this is the input text"; 
    byte[] Cipher; 
    System.out.println("input:\n" + TextStream); 
    Cipher = encrypt(TextStream); 
    System.out.println("cipher:\n" + base64.encodeAsString(Cipher)); 
    System.out.println("decrypt:\n" + decrypt(Cipher)); 
} 

private static byte[] encrypt(String Buffer) { 
    try { 

     Cipher rsa; 
     rsa = Cipher.getInstance("RSA"); 
     rsa.init(Cipher.ENCRYPT_MODE, getPrivateKey(PRIVATE_PATH)); 
     return rsa.doFinal(Buffer.getBytes()); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 


private static String decrypt(byte[] buffer) { 
    try { 
     Cipher rsa; 
     rsa = Cipher.getInstance("RSA"); 
     rsa.init(Cipher.DECRYPT_MODE, getPrivateKey(PUBLIC_PATH)); 
     byte[] utf8 = rsa.doFinal(buffer); 
     return new String(utf8, "UTF8"); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 

public static PrivateKey getPrivateKey(String filename) throws Exception { 
    File f = new File(filename); 
    FileInputStream fis = new FileInputStream(f); 
    DataInputStream dis = new DataInputStream(fis); 
    byte[] keyBytes = new byte[(int) f.length()]; 
    dis.readFully(keyBytes); 
    dis.close(); 

    PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); 
    KeyFactory kf = KeyFactory.getInstance("RSA"); 
    return kf.generatePrivate(spec); 
} 

public static PublicKey getPublicKey(String filename) throws Exception { 
    File f = new File(filename); 
    FileInputStream fis = new FileInputStream(f); 
    DataInputStream dis = new DataInputStream(fis); 
    byte[] keyBytes = new byte[(int) f.length()]; 
    dis.readFully(keyBytes); 
    dis.close(); 

    X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes); 
    KeyFactory kf = KeyFactory.getInstance("RSA"); 
    return kf.generatePublic(spec); 
} 

pero no las obras, la PKCS8EncodedKeySpec/X509EncodedKeySpec no son correctas ... pero no saben qué poner

+0

Y el problema es que ...? –

+0

mi intento no funcionó – caeycae

+2

[Stack Overflow no es un lector de Mind.] (Http://meta.stackexchange.com/a/128551/133242) –

Respuesta

5
No

seguro exactamente lo que estás pidiendo, pero creo que usted está teniendo problemas para leer Archivos PEM. El JPA no admite directamente el formato PEM. Tiene dos opciones, ya sea convertirlos a archivos codificados DER (puede usar openSSL para hacer esto) o puede usar la API Bouncy Castle para leer (o escribir) archivos PEM. la clase que te interese se llama PEMReader (y quizás también PEMWriter). Here is the Javadoc en el sitio web de bouncycastle.

12

Solución:

Gracias a @Sanjeev, utilizando el API castillo hinchable, yo era capaz de encriptar/decript con las claves generadas por OpenSSL

public static void main(String[] args) throws IOException { 

    Security.addProvider(new BouncyCastleProvider()); 

    KeyPair keyPair = readKeyPair(new File(PRIVATE_PATH), "pass"); 
    // if the private key is not encripted, pass can be anything. 
    Key publickey = readPublicKey(new File(PUBLIC_PATH), "pass"); 
    Base64 base64 = new Base64(); 
    String text = "this is the input text"; 
    byte[] encripted; 
    System.out.println("input:\n" + text); 
    encripted = encrypt(keyPair.getPublic(), text); 
    System.out.println("cipher:\n" + base64.encodeAsString(encripted)); 
    System.out.println("decrypt:\n" + decrypt(keyPair.getPrivate(), encripted));   
} 

private static byte[] encrypt(Key pubkey, String text) { 
    try { 
     Cipher rsa; 
     rsa = Cipher.getInstance("RSA"); 
     rsa.init(Cipher.ENCRYPT_MODE, pubkey); 
     return rsa.doFinal(text.getBytes()); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 


private static String decrypt(Key decryptionKey, byte[] buffer) { 
    try { 
     Cipher rsa; 
     rsa = Cipher.getInstance("RSA"); 
     rsa.init(Cipher.DECRYPT_MODE, decryptionKey); 
     byte[] utf8 = rsa.doFinal(buffer); 
     return new String(utf8, "UTF8"); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 

private static KeyPair readKeyPair(File privateKey, String keyPassword) throws IOException { 
    FileReader fileReader = new FileReader(privateKey); 
    PEMReader r = new PEMReader(fileReader, new DefaultPasswordFinder(keyPassword.toCharArray())); 
    try { 
     return (KeyPair) r.readObject(); 
    } catch (IOException ex) { 
     throw ex; 
    } finally { 
     r.close(); 
     fileReader.close(); 
    } 
} 

private static Key readPublicKey(File privateKey, String keyPassword) throws IOException { 
    FileReader fileReader = new FileReader(privateKey); 
    PEMReader r = new PEMReader(fileReader, new DefaultPasswordFinder(keyPassword.toCharArray())); 
    try { 
     return (RSAPublicKey) r.readObject(); 
    } catch (IOException ex) { 
     throw ex; 
    } finally { 
     r.close(); 
     fileReader.close(); 
    } 
} 
+1

¿No debería ser "UTF-8"? – drew

+4

Hola @caeycae, te estoy siguiendo publicación, también tengo problemas en esto. ¿En qué JAR/Library contiene DefaultPasswordFinder? – danisupr4

+0

¿Encontró una solución para qué archivo jar tenemos que incluir para DefaultPasswordFinder? – sasi

Cuestiones relacionadas