miércoles, 2 de enero de 2008

Cadenas seguras y POO.

Como en todos los proyectos, en este (la certificación) también me ha pillado el toro y estoy estudiando a marchas forzadas para presentarme al examen en febrero. Por ello he tardado tanto en hacer otra entrada.

Ahora mismo estoy machacando todo el tema de seguridad y me ha llamado la atención la poca o nula información e implementación de buenas maneras con respecto a la seguridad de la información que observo tanto en mi pasado laboral como en las decenas de compañeros con quienes he trabajado.

Ninguno teníamos en cuenta que con traceando la memoria (algo simple y sencillo) se puede acceder a esa información a la que NADIE debería acceder, menos su destinatario.

Por ello un pequeño capítulo al final del temario de seguridad me ha llamado poderosamente la atención y también me ha servido para hacer un poquito de programación orientada a objetos que, vergüenza la mía, tiene poquito que ver con la programación que he realizado antes de este curso.

OBJETIVO: Quiero coger una cadena de texto, y poderla codificar y recuperar de forma sencilla. De forma que nadie la pueda leer en la memoria. Y que cuando la use, desaparezca todo rastro de su contenido.

Pues bien, en antiguos y cercanos tiempos, hubiera escrito dos o tres mil líneas para obtener lo que obtengo con la clase que he escrito a continuación y que me parece de lo más elegante.

Private Class cadenaSegura
‘Declaro dos campos de la clase.
Dim cadena As String = String.Empty
Dim clave As SecureString

‘ En la declaración New instancio una nueva clase SecureString
‘ que me hace almacena el string en memoria pero codificandolo
‘ con DPAPI. Le asigno el texto a el campo cadena y que me
‘ lo codifique.
Public Sub New(ByVal texto As String)
clave = New SecureString
cadena = texto
codifica()
End Sub

‘ Método que codifica el campo cadena dentro de la cadena segura clave.
Public Sub codifica()
For Each letra As Char In cadena
clave.AppendChar(letra)
Next
‘ Hago la clave solo de lectura para que no se pueda modificar por nadie.
clave.MakeReadOnly()

End Sub

‘ Y siguiendo el consejo del Guille, sustituyo el método
‘ toString para que automáticamente me decodifique la
‘ cadena segura almacenada en el campo clave y me lo
‘ devuelva como una cadena de texto.
Public Overrides Function ToString() As String

‘ Como vés no es una tarea directa. Ya que realmente
‘ clave es un puntero que señala una dirección de
‘ memoria a la que se accede por medio de una estructura
‘ tipo IntPtr.
Dim bstr As IntPtr = Nothing
bstr = Marshal.SecureStringToBSTR(clave)
cadena = Marshal.PtrToStringAuto(bstr)

‘ Esto borra la cadena segura sobreescribiendo de ceros
‘ la posición de memoria que ocupaba.
Marshal.ZeroFreeBSTR(bstr)
Return cadena

End Function

End Class

Para mí lo más elegante viene ahora. El cómo usar esta clase.

Instacio la clase mándandole como parámetro el texto que quiero convertir en una cadena segura. Y luego, para recuperar el contenido de la cadena segura, simplemente llamo al método .toString.

Dim texto As New cadenaSegura(TextBox6.Text)
hash.Text = texto.ToString


Que bonita es la POO!!

No hay comentarios: