¿Cómo almacenar nombre de usuario y contraseña para API en la opción de wordpress DB?

19

Actualmente estoy desarrollando un complemento y es muy probable que lo publique en el repositorio de complementos públicos para que otros puedan usarlo.

El complemento usará una API y para usar esta API debe pasar un nombre de usuario y contraseña. Por lo tanto, mi complemento necesita almacenar estas credenciales de inicio de sesión en la base de datos. No quiero almacenarlos en texto sin formato, aunque la API los necesita en texto sin formato.

Entonces, mi pregunta es ¿cómo almaceno esta información confidencial? Hashing está fuera, por lo que tiene que ser algún tipo de cifrado.

En WordPress, ¿hay una clave única que se pueda usar que difiera de un blog a otro? ¿Qué funciones de php debo usar para cifrar y descifrar? Estoy buscando funciones que probablemente funcionen en todas las instalaciones de WP.

Brady
fuente
3
Esto es un poco insoluble. No importa cuánto cifre si necesita ser reversible. Si WP puede descifrarlo y WP está comprometido, entonces el cifrado no importa.
Rarst
Pero, ¿por qué su API necesita saber la contraseña? ¿No es suficiente si la API sabe que el usuario conoce la contraseña?
onetrickpony
1
@One Trick Pony: la contraseña debe almacenarse para que el proceso pueda automatizarse sin la intervención del usuario.
Brady
1
@Rarst: soy consciente de que si WP se ve comprometido, también lo están las contraseñas. No puedo evitar esto. Lo que puedo evitar es que si se obtiene un volcado de SQL, las contraseñas no están en texto plano.
Brady
@Brady, sí, si solo el volcado SQL se ve comprometido, el cifrado ayudaría. Sin embargo, encuentro tal escenario poco probable. Si tiene acceso a la base de datos, también es trivial comprometer WP.
Rarst

Respuestas:

4

Si bien estoy de acuerdo con las respuestas anteriores, para responder la pregunta que realmente hizo, lo que viene a la mente es utilizar una de estas constantes para wp-config.php:

define ('AUTH_KEY', 'redactado');
define ('SECURE_AUTH_KEY', 'redactado');
define ('LOGGED_IN_KEY', 'redactado');
define ('NONCE_KEY', 'redactado');

Están destinados a ser únicos en todas las instalaciones de WordPress, y son casi las únicas opciones para las claves preexistentes que se encuentran en WordPress. Alternativo sería agregar su propia constante similar que se construye al mezclar una de ellas con la dirección de correo electrónico del administrador o similar, y luego almacenarla en una opción de configuración oculta, para proteger contra la pérdida de su clave si alguien modifica accidentalmente las claves después de su El complemento está instalado. El peligro es que si no se hicieron únicos en la instalación inicial, pero el administrador / propietario del sitio decide rectificar la falla después del hecho, no deberían romper accidentalmente el cifrado de su contraseña.

En cuanto a las funciones de cifrado / descifrado: una búsqueda rápida en Google devuelve la siguiente lista con el código que parece ajustarse a la factura: http://maxvergelli.wordpress.com/2010/02/17/easy-to-use-and-strong- cifrado-descifrado-funciones-php /

función encriptar ($ input_string, $ key) {
    $ iv_size = mcrypt_get_iv_size (MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
    $ iv = mcrypt_create_iv ($ iv_size, MCRYPT_RAND);
    $ h_key = hash ('sha256', $ clave, VERDADERO);
    return base64_encode (mcrypt_encrypt (MCRYPT_RIJNDAEL_256, $ h_key, $ input_string, MCRYPT_MODE_ECB, $ iv));
}

descifrar la función ($ encrypted_input_string, $ key) {
    $ iv_size = mcrypt_get_iv_size (MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
    $ iv = mcrypt_create_iv ($ iv_size, MCRYPT_RAND);
    $ h_key = hash ('sha256', $ clave, VERDADERO);
    return trim (mcrypt_decrypt (MCRYPT_RIJNDAEL_256, $ h_key, base64_decode ($ encrypted_input_string), MCRYPT_MODE_ECB, $ iv));
}

Aquí hay alguna documentación del cifrado AES utilizado aquí: http://www.chilkatsoft.com/p/php_aes.asp

marfarma
fuente
4

Esta es exactamente la circunstancia para la que OAuth fue diseñada.

Desde la página de inicio de OAuth :

Para desarrolladores de proveedores de servicios ...

Si estás apoyando ...

  • aplicaciones web
  • API del lado del servidor
  • mashups

Si está almacenando datos protegidos en nombre de sus usuarios, no deberían difundir sus contraseñas en la web para acceder a ellas. Use OAuth para dar a sus usuarios acceso a sus datos mientras protege las credenciales de su cuenta.

La ventaja de OAuth es que no necesita almacenar la contraseña del usuario. Cuando configuran el complemento por primera vez, se les pide que inicien sesión con un nombre de usuario y contraseña a través de la aplicación (generalmente una página alojada en el mismo servidor que la API y cargada en una redirección de página, un cuadro grueso o un iframe) .

Una vez que el usuario inicia sesión, el servidor (su sistema) crea una clave segura que su sistema (WordPress) puede usar para interactuar con la API. Esta clave es única para la cuenta de usuario y el sitio, y le da permiso a la aplicación (en WordPress) para hacer cosas con la API en nombre del usuario sin pasar su información de autenticación cada vez.

Si desea ver un ejemplo de esto en acción, consulte Jetpack .

Cuando activa el complemento, se queja de que no está conectado. Cuando lo "conecta", ingresa sus credenciales a través de WordPress.com y configura la interacción OAuth entre WordPress y su API.

Pero solo tiene que hacer esto una vez y su nombre de usuario / contraseña de WordPress.com nunca se almacena en su base de datos local de WordPress.

EAMann
fuente
1
Sería bueno usar esto, pero la API con la que estoy tratando no es mía y no tienen un sistema OAuth.
Brady
1
En ese caso, su única opción real es aceptar que necesita almacenar la contraseña en la base de datos y si la encripta o no, realmente no hace ninguna diferencia sustancial a la seguridad. Como otros han mencionado anteriormente, si está en la base de datos y el cifrado es reversible, cualquier persona con acceso a WordPress (legítimo o pirateado) podría obtenerlo.
EAMann
0

Este es un problema importante, ya que muchos servicios aún no son compatibles con OAuth y el almacenamiento de contraseñas en la base de datos de opciones los hace legibles para cada complemento de Wordpress (vea mi comentario más arriba).

Esta no es (todavía) una respuesta real a la pregunta, pero también es demasiado larga para un comentario. Espero iniciar una discusión con esto, con el objetivo de encontrar la "mejor" solución posible a este problema "irresoluble".

La idea básica que me hace pensar que es posible cifrar contraseñas es la siguiente:

Hay una pieza de información secreta que cada usuario tiene: su contraseña de Wordpress. Debería ser posible almacenar credenciales en servicios de terceros encriptados con un formulario secreto derivado de esa contraseña y solo descifrarlos cuando el usuario haya iniciado sesión.

De esta manera, debería ser posible al menos hacer que sea imposible robar las contraseñas de una copia de los archivos y la base de datos de Wordpress. No puede resolver el problema de que otros complementos roben credenciales, porque cada complemento puede capturar la contraseña de texto sin formato durante el inicio de sesión.

En realidad, el descifrado es bastante fácil de hacer: supongamos que ya tenemos una versión encriptada del servicio de terceros almacenada en la base de datos, podemos conectarla al 'authenticate'filtro o al sobrescribir la wp_authenticate()función, generar un hash salado de la contraseña de usuario de texto sin formato (por medios de wp_hash_password()), almacene esa contraseña cifrada como clave de cifrado en algún lugar privado hasta que el usuario cierre sesión (use el 'wp_logout'gancho para eliminar la clave) y úsela cada vez que necesitemos la contraseña de un tercero para descifrar el valor cifrado en la base de datos.

Si bien tengo la sensación de que debería ser posible hacer que esto funcione, sin embargo, hay varios problemas sin resolver:

  1. ¿Cómo hacer el cifrado? Potencialmente, uno podría almacenar la contraseña de texto sin formato hasta que el usuario cierre sesión y vuelva a ingresar y realice el cifrado durante 'authenticate'. Se le podría solicitar al usuario que inicie sesión para mantener el período hasta que esto ocurra brevemente.
  2. ¿Dónde almacenar la clave y cómo eliminarla durante el cierre de sesión? ¿Entiendo correctamente que 'authenticate'solo se ejecuta cuando el usuario realmente inicia sesión?
  3. En caso de que ahora haya una manera de almacenar la contraseña hash, ¿tal vez se pueda derivar una clave de la cookie de sesión?
  4. ¿Quién manejará los cambios de contraseña? Parece que es posible detectar dichos cambios de contraseña, y la contraseña de un tercero tendría que volver a cifrarse con la clave derivada de la nueva contraseña.
  5. ¿Hay alguna manera de proporcionar soporte multiusuario? Idealmente, uno desearía que un usuario administrador pudiera establecer contraseñas de terceros en la configuración que luego pueden ser demandadas por usuarios menos privilegiados para interactuar con servicios de terceros, idealmente incluso sin revelar esas contraseñas. Para esto, el usuario administrador debería poder generar una clave para todos los usuarios que esos otros usuarios solo pueden generar por sí mismos. ¿Es eso de alguna manera posible?
cgogolin
fuente