2010-06-14 22 views
10

Mi aplicación hace uso de la clase RijndaelManaged para encriptar datos. Como parte de este cifrado, uso un objeto SecureString cargado con una contraseña que get se convierte en una matriz de bytes y se carga en la clave del objeto administrado por Rajindael en el tiempo de ejecución.¿Almacenar de forma segura una contraseña en el código del programa?

La pregunta que tengo es el almacenamiento de este SecureString. Se puede ingresar una contraseña ingresada por el usuario en tiempo de ejecución, y eso puede cargarse "de forma segura" en un objeto SecureString, pero si no se ingresa una contraseña, el usuario debe establecer un valor predeterminado.

Así que en última instancia la quesiton se reduce a:

Si tengo que tener alguna conocida cadena o matriz de bytes para cargar en un objeto SecureString cada vez mis ejecuta la aplicación, ¿cómo puedo hacer eso? Los datos "encriptados" finalmente son descifrados por otra aplicación, por lo que incluso si ningún usuario ingresó una contraseña, aún necesito que los datos se cifren mientras pasa de una aplicación a otra. Esto significa que no puedo hacer que la contraseña predeterminada sea aleatoria, porque la otra aplicación no podrá descifrarla correctamente.

Una posible solución que estoy pensando es crear un dll que solo escupe una sola frase de contraseña, luego utilizo esa frase de contraseña y la ejecuto a través de un par de funciones de hashing/reorganización diferentes en tiempo de ejecución antes de alimentarlo finalmente objeto secureString ¿Sería esto lo suficientemente seguro?

Editar Para mayor claridad *: los datos cifrados se pasan a través de archivos entre máquinas. Piense en ello como un archivo Zip que siempre tiene una contraseña, se asume una predeterminada si el usuario no ingresa nada directamente.

Respuesta

8

No tiene sentido encriptar simétricamente con una cadena que está codificada en su ejecutable. Solo dará una falsa sensación de seguridad. Ninguna cantidad de hashing corrige este esquema.

Vea this Pidgin FAQ para el mismo punto en un contexto diferente.

No tengo claro por qué cree que necesita cifrar la comunicación entre aplicaciones. Si esta comunicación es local para la máquina, entonces no veo la necesidad de cifrado, en particular el cifrado que no es específico del usuario. ¿Es esto un esquema de DRM?

EDITAR: Si se está transfiriendo a una máquina diferente, quizás pueda codificar un public key, y luego hacer que la otra máquina se decodifique con la clave privada correspondiente.

+0

He leído la pregunta como una alternativa a la codificación de la cadena en primer lugar. – Serapth

+0

No es local para la máquina, los datos cifrados terminan en xml que luego se transfiere a una máquina diferente (sin embargo, no es posible la conexión directa). – Nick

+0

+1 Estoy totalmente de acuerdo con Pidgin. – rook

2

Este artículo en securing SQL connection strings debe ser igual de aplicable para almacenar contraseñas encriptadas, donde permite que el SO maneje el cifrado de la semilla de salazón para su descifrado.

6

Déjame abordar tu última pregunta primero.

"¿Esto sería lo suficientemente seguro?"

El único que puede responder es usted. Nadie aquí sabe lo que significa "lo suficientemente seguro" en el contexto de su solicitud.

¿Estás creando una aplicación para guardar el diario de las adolescentes? Claro, sería "lo suficientemente seguro".

¿Está creando una aplicación para cifrar información o autenticación para sistemas seguros de grado militar? No, ni siquiera cerca.

Solo puede confiar en un tipo de seguridad si tiene la intención de almacenar la contraseña en su código fuente y, por lo tanto, es ejecutable, y eso es security by obscurity.

Si su problema es que no puede, o no quiere, almacenar la contraseña en el código fuente, al moverla a un dll diferente no se resuelve nada, acaba de mover el problema a un proyecto diferente.

Sin embargo, me pregunto algo. Usted dice "Tengo que hacer algo de manera predeterminada". ¿Es asi? ¿Está intentando almacenar un valor predeterminado para la cadena de contraseña segura en el código fuente? ¿Qué tal "THISISNOTAPASSWORD"?

+6

Los ciberdelincuentes también son muy listos para ser engañados por THISISNOTAPASSWORD. En cambio, le sugiero que emplee la psicología y vaya con THISISAPASSWORD. – Serapth

+0

Si este problema de hackeo me fue asignado, estaré realmente confundido con este juego psicológico. : P – Fraga

+0

+1 para verificar que es lo suficientemente seguro. –

2

Me parece que quizás deba utilizar una solución PKI en lugar de cifrado/descifrado. Si tiene otra aplicación que necesita consumir los datos cifrados, puede tener un par de claves para esa aplicación y dar la clave pública a la aplicación que está haciendo el cifrado. De esta forma, aún mantendrá sus datos seguros, pero no introducirá un montón de código adicional que finalmente no brinda tanta protección.

Una rápida búsqueda en Google me dio this artículo Proyecto Código que habla sobre el uso del almacén de certificados de Windows en .Net

6

Eric Lippert You Want Salt With That? (original blog post)

Lea también su puesto para Use the right tool for the job donde termina con la consejos siguientes:

0) Si puede, simplemente no vaya allí. El cifrado es extremadamente difícil de resolver y, en primer lugar, a menudo es la solución equivocada. Use otras técnicas para resolver sus problemas de seguridad.

1) Si el problema es un cliente no confiable, entonces no construya una solución de seguridad que requiera confiar en el cliente.

2) Si puede usar piezas disponibles en el mercado, hágalo.

3) Si no puede usar piezas listas para usar y tiene que usar un criptosistema, entonces no use un criptosistema que no comprenda del todo.

4) Si tiene que usar un criptosistema que no comprende por completo, al menos no lo use para resolver problemas que no fue diseñado para resolver.

5) Si tiene que utilizar un criptosistema para esquiar entre los árboles, al menos no permita que el cliente, presumiblemente hostil, elija el mensaje cifrado. Elija el token usted mismo. Si el token debe incluir información del cliente, desinféctelo de alguna manera; requiere que sea solo texto ASCII directo, inserte espacios en blanco aleatorios, etc.

6) Si tiene que permitir que el cliente elija el token, no cifre el token. Firme un hash criptográficamente seguro del token. Es mucho más difícil para el atacante elegir un token que produzca un hash deseado.

7) No utilice el mismo par de claves para encriptar los mensajes salientes como lo hace para proteger los mensajes entrantes. Obtenga un par de claves para cada operación lógicamente diferente que va a realizar.

8) Encripte las comunicaciones en ambos sentidos.

9) Considere tener un mecanismo de revocación, de modo que una vez que sepa que Eve lo está atacando, al menos puede revocar su licencia. (O puede revocar una licencia comprometida conocida, y así sucesivamente.)

Cuestiones relacionadas