Cómo minimizar el riesgo de seguridad al tener que trabajar con contraseñas desencriptadas (texto sin formato) debido al diseño de API de terceros

3

Estoy desarrollando una aplicación (C #) para la plataforma Microsoft SharePoint que usa la tecnología de almacenamiento remoto de BLOB (RBS) de SQL Server (2008 R2). Para realizar ciertas tareas del lado del cliente, debo obtener el par de nombre de usuario y contraseña de la base de datos y pasarlo a un constructor que se parece a esto ( MSDN ):

public BlobStoreCredentials(string credentialName, byte[] credentialSecret)

Tenga en cuenta que credentialSecret aquí espera una contraseña descifrada ; la contraseña se cifra internamente después de la llamada del constructor.

Microsoft, por razones que desconozco, by-design almacena contraseñas de RBS que puedo enviar al constructor anterior cifrado simétricamente en la base de datos, con la clave de cifrado almacenada dentro de la misma base de datos (para crear / insertar contraseñas, se utiliza un procedimiento almacenado proporcionado por Microsoft que acepta una contraseña de texto sin formato). Por lo poco que sé sobre seguridad, esto no es correcto, ¿verdad?

Para obtener un byte[] credentialSecret válido, aparentemente se supone que debo usar una consulta que se parece a esto y devuelve el nombre de usuario y la contraseña descifrada:

OPEN SYMMETRIC KEY skey
DECRYPTION BY CERTIFICATE cert;

SELECT [username], CONVERT(nvarchar, DecryptByKey(password)) 
FROM [credentials] 
WHERE [id]=@userId;

Luego puedo ingresar la contraseña descifrada al constructor (del lado del cliente) que la cifra internamente, la utiliza para realizar algunas tareas y dispone las credenciales al final (consulte el código de ejemplo de MSDN más arriba).

Me parece que muchas cosas están muy mal con este diseño. Incluso si decidiera implementar una base de datos ortogonal personalizada para almacenar solo contraseñas de hash unidireccionales, en algún momento necesitaría "descifrarlas" a texto sin formato para enviarlas al constructor anterior.

Mi pregunta es, ¿hay formas de minimizar razonablemente los problemas de seguridad con este enfoque al tiempo que se acepta la premisa de la pregunta (es decir, debo pasar las credenciales desencriptadas al constructor), o es este diseño inherentemente tan inseguro que está más allá de la mejora? No es solo el aspecto técnico, sino también sobre cómo comunicar situaciones como esta al empleador y cómo reaccionar (como un individuo que no es de seguridad) en general cuando se trata de una situación que parece obligarme a usar un diseño de seguridad incorrecto. La solución que presenté obviamente funciona, pero es, por lo que sé, mala seguridad, por no mencionar que se parece a un dispositivo Rube Goldberg.

(Pido disculpas si esta pregunta no es lo suficientemente específica para este sitio, pero no sé dónde evaluar mis opciones)

    
pregunta w128 15.04.2014 - 14:29
fuente

1 respuesta

1

No he usado estas tecnologías antes, pero lo que puedo decir es que si descifra la contraseña en su consulta SQL, cualquiera en su red puede rastrear y obtener las contraseñas como texto simple.

Si entiendo correctamente, ¿tu C # obtendrá las contraseñas desencriptadas? Si es así, le recomendaría que tuviera algo como en su aplicación de C #:

  1. C # genera una clave aleatoria (utilizada para salt en su cifrado) y envía sal a un procedimiento almacenado en SQL.
  2. El procedimiento almacenado cifrará la contraseña basándose en el salt (del cliente)
  3. C # lo descifra según la clave de sal que proporcionó

El atacante podría descifrarlo si obtuviera la sal aleatoria y la ingeniería inversa de su C # (lo cual es muy fácil debido a los códigos de bytes), pero al menos no es texto simple o cifrado estático y mucho mejor que su simple -text.

    
respondido por el Paul 15.04.2014 - 15:20
fuente

Lea otras preguntas en las etiquetas