Cifrar datos en Android con un archivo RSA public.pem generado en Ruby

Perdón por hacer una pregunta en particular, pero necesito generar en código java una 'firma' como la siguiente línea de código en ruby:

signature = OpenSSL::PKey::RSA.new(File.read("PUBLIC_PEM_PATH")).public_encrypt('SECRET_KEY')

Tengo el archivo de la llave del .pem y el SECRET_KEY que es algo como: F6qxlwQTYWRM3gRfgftryKJHKYZiGXdoy5lDm4

Cómo puedo hacer esto ?

¡Gracias!

ACTUALIZACIÓN 1 He intentado esto:

 File pubKeyFile = new File(keyFileName); DataInputStream inputStream; byte[] signature = null; try { inputStream = new DataInputStream(new FileInputStream(pubKeyFile)); byte[] pubKeyBytes = new byte[(int)pubKeyFile.length()]; inputStream.readFully(pubKeyBytes); inputStream.close(); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubKeyBytes); RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(pubSpec); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, pubKey); signature = cipher.doFinal(secretKey.getBytes()); } catch (Exception e) { e.printStackTrace(); } return signature; 

Y tiene este error:

 java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag 

UPDATE2 He logrado cargar una clave pública desde un archivo .pem. Pero ahora, estoy recibiendo un error de la cifra.

 public static byte[] getSignature(String keyFileName, byte[] secretKey){ byte[] signature = null; try { PublicKey pubKey = readKeyFromFile(keyFileName); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, pubKey); signature = cipher.doFinal(secretKey); } catch (Exception e) { e.printStackTrace(); } return signature; } private static PublicKey readKeyFromFile(String keyFileName) throws IOException { InputStream in = new FileInputStream(keyFileName); DataInputStream din = new DataInputStream(in); try { BigInteger m = BigInteger.valueOf(din.readLong()); BigInteger e = BigInteger.valueOf(din.readLong()); RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e); KeyFactory fact = KeyFactory.getInstance("RSA"); RSAPublicKey pubKey = (RSAPublicKey) fact.generatePublic(keySpec); return pubKey; } catch (Exception e) { throw new RuntimeException("Spurious serialisation error", e); } finally { din.close(); } } 

El registro de errores:

 javax.crypto.IllegalBlockSizeException: input must be under 8 bytes 

¿¿Alguna idea??

Así que finalmente, después de horas de investigación, vine con una solución y finalmente pude obtener mi clave pública de archivo .pem y generar una instancia de esta clave. Por lo tanto, logré cifrar los datos.

Pero tuve que copiar y pegar el contenido de la clave sin ningún carácter especial como '\ n' y hacer una publicKeyString con ella

———- COMIENZA LA LLAVE PUBLICA DE RSA ———

Contenido clave

———- END RSA PUBLIC KEY ———

 static public PublicKey publicKey(String publicKeyString) { try { byte[] decodedPublicKey = Base64.decode(publicKeyString, 0); ASN1InputStream in = new ASN1InputStream(decodedPublicKey); ASN1Primitive obj = in.readObject(); RSAPublicKeyStructure keyStruct = RSAPublicKeyStructure.getInstance(obj); RSAPublicKeySpec keySpec = new RSAPublicKeySpec(keyStruct.getModulus(), keyStruct.getPublicExponent()); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return keyFactory.generatePublic(keySpec); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } 

Fallé incluso cuando intenté usar PEMReader del castillo hinchable. Todos los problemas tienen algo que ver con las claves generadas en la versión anterior de Ruby 1.9.3 como se describe con detalles aquí .

De todos modos, muchas gracias por la atención dispuesta.

Parece que la envoltura de claves (cifrado) para mí. Usa bouncy castle para leer el archivo PEM, luego usa Cipher.getInstance("RSA/ECB/PKCS1Padding") para cifrar la clave secreta y base 64 codifica el resultado … También puedes probar el modo Cipher.WRAP_MODE para ver si eso funciona. Tenga en cuenta que el cifrado siempre devolverá un resultado diferente, la única manera de comprobar la compatibilidad es descifrarlo con el otro software.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.