Compartir y almacenar RSA – key pública en el server java y viceversa

Mis requisitos son:

Requisito 1: compartir key pública en el server java.

Pasos:

  1. Genera keys público-privadas en la aplicación iOS.
  2. Almacene las llaves generadas en llavero.
  3. Envía key pública generada al server java.
  4. El server Java podrá almacenar keys públicas compartidas en la database.

Requisito 2: Almacenar key pública enviada por el server Java.

Pasos:

  1. El server Java envía una key pública de otro usuario.
  2. Procese los datos enviados por el server java y genere una key pública desde él.
  3. Almacene la key generada en el llavero, que luego se puede recuperar para cifrar el post que se va a transferir.

Puedo lograr los pasos 1-2 en el requisito 1 utilizando el método a continuación definido en la class SecKeyWrapper (ejemplo CommonCrypto):

- (void)generateKeyPair:(NSUInteger)keySize 

Pregunta 1: ahora el problema es : ¿cómo debo enviar esa key al server java?

Tenemos el método getPublicKeyBits en la misma class, que devuelve un object NSData, en algunas búsquedas en Google encontré que está en formatting codificado DER.

Pregunta 2: Si envío el mismo object NSData al server, que supongo que interpretará como el object ByteBuffer, ¿será posible que otros dispositivos, en mi caso Android, interpreten esa información?

Pregunta 3: ¿Cuál es la mejor manera de compartir la key pública en los escenarios anteriores?

Esto es lo que trato de lograr desde algunos días:

Enfoque n. ° 1: tratando de generar key pública a partir de exponente y module

Fin de Android

  1. Clave pública y privada generada en un dispositivo Android (con un contenedor openssl)
  2. Obtuvo module y exponente de la key pública generada.

Fin de iOS

  1. Clave pública generada a partir de module y exponente, en ios end, utilizando el código especificado en este enlace: https://stackoverflow.com/a/10643962/217586
  2. Se convirtió una cadena de ejemplo a un object de NSData utilizando NSUTF8StringEncoding
  3. Utilizado: wrapSymmetricKey: keyRef: método definido en la class SecKeyWrapper (ejemplo de CryptoExercise) para el encryption, y la key pasajera obtenida del paso 1 y los datos para encriptar obtenidos del paso 2 en él
  4. Los NSData convertidos (datos encriptados) obtenidos en el paso anterior a la cadena base64 codificada, compartieron lo mismo con el tipo de Android

Fin de Android

  1. Intenté descifrar la cadena base64 codificada, utilizando la key privada relacionada

Problema:

Obtiene error: demasiados datos para bloquear RSA.

Acercamiento n. ° 2: (Conseguí saber en este enlace que: https://github.com/superwills/iOSRSAPublicKeyEncryption , se supone que no debemos cargar keys públicas en iOS a partir de otra cosa que no sea un certificate, por lo que intentamos un enfoque diferente)

Terminal final

  1. Certificado generado con los commands openssl especificados en esta url: https://stackoverflow.com/a/17295321/217586

Fin de iOS

  1. Se obtuvo una key pública como se especifica en la URL anterior.
  2. Se usa el siguiente código para encriptar los datos:

    SecKeyWrapper * secKeyWrapper = [SecKeyWrapper shanetworkingWrapper]; SecKeyRef obtuvoPublicKey = [secKeyWrapper getPublicKeyRefFromDerCertificate: kCertificatePath]; NSData * dataToBeEncrypted = [kStringToBeEncrypted dataUsingEncoding: NSUTF8StringEncoding]; NSData * encryptedText = [secKeyWrapper wrapSymmetricKey: dataToBeEncrypted keyRef: obtainedPublicKey];

  3. NSData convertido a base64 cadena codificada

Terminal final

  1. Se usa el command debajo para convertirlo nuevamente a la cadena original:

    eco openssl rsautl -decrypt -inkey rsaPrivate.pem

Problema:

error: rutinas rsa: RSA_EAY_PRIVATE_DECRYPT: datos mayores que mod len: /SourceCache/OpenSSL098/OpenSSL098-47.1/src/crypto/rsa/rsa_eay.c

¿Alguna sugerencia?

Su primer enfoque es casi el mismo que utilicé en un proyecto hace time. La diferencia es que no estaba compartiendo el module y el exponente sino toda la key pública codificada en la base 64 (sin el encabezado / pie de página —– BEGIN / END PUBLIC KEY —–), convirtiéndolo hacia atrás y hacia atrás para las classs apropiadas en el dispositivo final. Básicamente, el mismo concepto se aplica a los datos encriptados, siempre comparte datos codificados en Base64 para evitar problemas de conversión. Hasta ahora su enfoque debería estar bien si no tuviera ningún problema de conversión (y puede encontrar problemas fácilmente al convertir las keys públicas a su representación base64, tanto en Android como en iOS, la cadena debería ser exactamente la misma, de lo contrario, sucedió algo malo ) El problema que tiene ( getting error - too much data for RSA block ) se debe a que el text que está cifrando es demasiado grande para el tamaño de key que proporcionó. RSA solo puede cifrar posts que son varios bytes más cortos que el module del par de keys, por lo tanto, el error. Lo que debería hacer es generar una key simétrica de encryption de una sola vez que se utiliza para cifrar / descifrar los datos, intercambiar los datos encriptados con la key simétrica y la key cifrada utilizando RSA. Así es como funciona más o less cualquier esquema de encriptación RSA correctamente diseñado.

De todos modos, creo que si intentas tu primer enfoque con una cadena fija más corta, deberías observar que el primer enfoque probablemente funcione (a less que hayas implementado las cosas incorrectamente, como explicas teóricamente correcto, pero es difícil de decir sin ver un código).

Antonio