openssl en PHP

NeB1

Buenas a todos,

Resulta que soy un poco pez en temas de seguridad, pero ahora necesito que la información que envío entre mis usuarios y mi servidor, esté encriptada mediante claves rsa. He visto que con openssl se puede hacer, pero no tengo muy claro como sería el proceso.

Cuando creo un usuario, le genero un par de claves. Me guardo la privada, ¿no? y al usuario que le doy, ¿la pública que se genera a partir de esa privada?

Soltrac

No se como funcionará el openSSL pero la idea de la encriptación RSA es que la clave pública te permite encriptar y la privada desencriptar.

Por eso siempre se distribuye la pública y nunca la privada. Tengo el mensaje, lo encripto con la pública y en la recepción lo desencripto con la privada.

1 respuesta
B

No es mas sencillo comprar un certificado ssl y solo permitir https en el dominio? O en su defecto lo autofirmas pero el cliente tendrá que aceptar el certificado.

1 1 respuesta
NeB1

Vale, es que no he explicado bien el proceso, pasaba de dar demasiados detalles xDD Digamos que mis 'usuarios' realmente no son usuarios, son gente, que tiene su propia web, y desde esa web, hace peticiones a mi servidor enviandome ciertos datos a través de un formulario.

El formulario en cuestión, el botón de enviar lo apreta un usuario de su web, con lo que los datos del formulario deben de estar encriptados para que el usuario no sepa que datos se envian a mi servidor. Entonces me llega el usuario de su web junto con datos por POST, yo hago ciertas cosas, y le devuelvo el usuario a su web, junto con otros datos por POST.

(en plan el me envía id_pedido y yo le devuelvo id_pedido, estado_transaccion, ok?)

Entonces la idea es para cada usuario generarle una par claves, que el sea el que firma los datos, y yo los desencripto en mi servidor, y se los vuelvo a enviar mediante la misma clave. Por lo tanto, son ellos los que firman, y además cada uno con su propia clave.

Espero que haya quedado más o menos claro que me he líado mogollón explicandolo. #3 y #2, YO OS INVOCO! (como mola el sistema de notificaciones xDD, solo falta poder escribir el nombre del usuario y que le salga una notificación también:P)

1 respuesta
Soltrac

#4 Pero al vovérselo a enviar como lo desencriptan ellos?

Necesitarías un sistema de claves simétrico no?

1 respuesta
NeB1

#5 Mmmmm... maybe? xD Si yo tengo su clave privada, y ellos también tienen la clave privada, se podrá cifrar con la única clave publica que tendremos en común y descifrar a partir de la privada, ¿no?

la parte de como la desencriptan ellos es un módulo para drupal que tengo que hacer yo también, así que lo puedo implementar como yo quiera. La idea era que en su panel de mi web se descarguen la key y la suban en el panel de administración del modulo de drupal.

Fr4nk0

Buenas

El uso de claves depende de lo que quieras hacer en tu aplicación y cómo quieras hacerlo.
Existen dos operaciones que aunque son parecidas se diferencian en algunos aspectos: Cifrar y Firmar.

Teniendo un par de claves (pública y privada) , si cifras algo con una clave pública, sólo el poseedor de la clave privada asociada a esa clave pública podrá descrifrar el mensaje encriptado. Digo el poseedor, porque lo normal es que la clave privada no se vaya repartiendo por ahi, sino que esté asociada a cada usuario/servicio/etc.

Si por el contrario vas a enviar información cifrada y quieres que cualquiera (que tenga tu clave pública claro) pueda ver esa información, se usa la clave privada para cifrar esa información.

Con esto ocultamos contenido.

Otra cosa es la firma, que se usa para comprobar la integridad de la información.
Para ello primero se hace un hash de la información, y se cifra con la clave privada dicho hash, que se enviará junto con la información.
Al recibirla, para comprobar que esa información no ha sido alterada, se hace el hash de la información otra vez y se comprueba que ese hash es idéntico al que se obtiene cuando se descifra el hash recibido con la clave pública.
Esto indica que el mensaje firmado no ha sido tocado, pero no quiere decir que porque lo firmes con tu clave privada lo hayas enviado tú, ya que si te pillan la clave pueden firmar cosas como si fueras tú.

Una vez dicho esto, y usando una de las dos operaciones (cifrar o firmar) que más se ajuste a tu aplicación, la solución que propones es la que me parece correcta.
Es decir, tú generas las claves y guardas ambas.
El usuario entra en su panel y se descarga su clave privada (o ambas) y las configura en el modulo de Drupal.

Ya en el modulo de Drupal es donde se debería encriptar o firmar la información que se envía a tu aplicación y usar las clave correspondiente en un extremo, según la que hayas utilizado en el otro.

Yo en la aplicación que estoy trabajando, como se basa en relaciones de confianza (me creo que nadie va a suplantar a nadie), utilizo operaciones de firma.

Espero no haberme equivocado en nada y que te sirva de ayuda.

2 respuestas
NeB1

#7 pues sí, si que me sirve de ayuda, muchas gracias ^^

2 respuestas
DarkSoldier

por cierto, bug ??? XDD has invocado a #3 y no ha salido, negrita ?? #8

edit: siii, bug #8

elkaoD

#8 no te sigue valiendo https? Los usuarios hacen los GETs o POSTs oportunos a tu servidor HTTP. Fin.

1 respuesta
NeB1

#10 no, imaginate que tienes un comercio electrónico y que un usuario realiza una compra.

el formulario de compra es tal como sigue:

<form action="url_del_banco">
    <input name="order_id">
    <input name="order_amount">
    <--- ETC --->
</form>

Y cuando un pago se realiza correctamente la TPV responde al script adecuado algo así

$_POST['order_id'] = X;
$_POST['approval_code'] = 000;

Pues bien, un usuario puede enviar esos datos a ese script (a no ser que realices comprobación de IP que en mi caso no me vale), y suplantar al banco y diciendo que el pago ya está realizado.

Por eso el tema de encriptar, para que la información que envío en este caso sería del rollo

$_POST['approval_code']="asou32m12Ž`123`+'023123!"3¡0'23";

xD y solo se podría leer el contenido con la llave del comercio.

1 respuesta
elkaoD

#11 pero tú puedes tener un host intermediario que es el que hace esas comprobaciones, y ese host es el que expone el interfaz al que accede el usuario. Más que nada, qué más da que tus clientes accedan a ti a través de una petición HTTP o directamente por socket cifrado, si al fin y al cabo les tienes que dar el script/programa que accede a la interfaz, y ese va a tener la clave de cifrado.

Igualmente tú sabrás mejor que yo la arquitectura de tu sistema xD Es sólo por dar ideas.

Beavis

Si lo que te interesa es simplemente comprobar la autenticidad del request y los datos no son sensibles con una simple firma bastaría.
Por ejemplo haces un sha1 de los parametros que se envian concatenados en cierto orden preestablecido añadiendo como salt una o varias claves que conozcan las 2 partes y añades el hash resultante como otro parametro más (firma). El lado que recibe solo tendría que repetir la operación utilizando los parámetros recibidos y la clave secreta que ya conoce y comprobar que la firma obtenida coincide con la recibida.

edit: vaya veo que #7 ya había explicado lo mismo sorry :x por si sirve de algo éste es el método que suelen usar los TPVs

LOc0

Pues bien, un usuario puede enviar esos datos a ese script (a no ser que realices comprobación de IP que en mi caso no me vale), y suplantar al banco y diciendo que el pago ya está realizado.

La entidad que no quiera ser suplantada es la que tiene que firmar sus mensajes. Es decir, en este caso el banco debería firmar su respuesta (cifrar con su clave privada) y tú, usando la clave pública del banco comprobar la firma.

Otra opción es que el banco y tú tengáis una clave secreta y el campo order_id del formulario vaya cifrado con esa clave. De esta forma nadie podrá suplantar al banco porque no sabrá el id. Pero vamos, necesitas colaboración del banco.

Salu2 ;)

1 respuesta
NeB1

#14 es que en este caso yo soy el banco y mis clientes el comercio. Al lo tengo ya todo más claro, los datos se envian codificados mediante AES256, y se descifran en ambos lados con la clave secreta. Además el canal se codificará mediante ssl, ya hemos pedido un certificado, para evitar bit flipping y cosas de esas.

Nada, gracias a todos ^^

Usuarios habituales