Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving a SecureString

One of the feature requests I've got for the program I'm working on is to be able to save the list of credentials users enter in, so they can be shared around. The specific use case that inspired this request was using our program on a large corporate network, made up of fairly good LANs connected by a flaky WAN. The idea was that, instead of having our program beat against the WAN when it's down, they'd send a 'configuration' file containing the closely-guarded admin credentials, run it in each LAN and zip up the results and e-mail it back.

Yeah.

My initial instinct is to scoff at this request - saving passwords? really? and surely the network division of the company would prefer you to try and sell whatever WAN products they have - but it turns out one of the classes I use the credentials for can take a SecureString, and, well, it's always good to look out for ways you can save people some effort. That got me to wondering:

Is it possible to save an encrypted SecureString, so that I can save the sensitive data to a file and open it up someplace else?

What are your thoughts, Stack Overflow?

like image 619
Merus Avatar asked Sep 29 '08 06:09

Merus


People also ask

How do I create a security SecureString?

SecureString operations. You instantiate a SecureString object by calling its parameterless constructor. You can add a single character at a time to a SecureString object by calling its AppendChar or InsertAt method.

Is SecureString secure?

SecureString is a . NET class that provides a more secure alternative to the String class because it maintains a single copy in memory. Please note that SecureString is part of the System. Security namespace.

What is SecureString in powershell?

The secure string cmdlets help protect confidential text. The text is encrypted for privacy and is deleted from computer memory after it is used. If you use this parameter to provide plain text as input, the system cannot protect that input in this manner.

What is SecureString in Java?

Secure string implementation that solves the problems associated with keeping passwords as java. lang. String . That is, anything represented as a String is kept in memory as a clear text password and stays in memory at least until it is garbage collected.


2 Answers

There is no save support in SecureString, it's intended as a mechanism to protect a in-memory managed string and is only used for interfacing with unmanaged APIs. If a password was stored in a System.String instance, security would be less due to the nature of System.String. The existence of garbage collection and interning would keep the password in memory longer than necessary. Also due to the plethora of great debugging tools for .NET, it would be significantly easier to access the string through reflection or another .NET API even without the longer lifetime.

If you're going to save a password on the disk your security is pretty far compromised. If someone has physical access to the machine, or administrator level remote access, then the best you can do is make it more difficult, but never impossible. Use an encryption API, store it in a secure location, configure access rights.

All that aside, Merus, I'd suggest you try to improve the overall system because for a use-case like you're describing (assuming I understand it) you'd be better served to store a hash than the actual password.

like image 152
nedruod Avatar answered Sep 19 '22 19:09

nedruod


You might want to look at comparing password hash.
You would have a salt made of username and probably some other constant, followed by the string. Then, you would pass that to a hashing algorithm, like SHA1*.
For instance,

using System.Security.Cryptography;

public byte[] GetPasswordHash(string username, string password, string salt)
{
    // get salted byte[] buffer, containing username, password and some (constant) salt
    byte[] buffer;
    using (MemoryStream stream = new MemoryStream())
    using (StreamWriter writer = new StreamWriter(stream))
    {
        writer.Write(salt);
        writer.Write(username);
        writer.Write(password);
        writer.Flush();

        buffer = stream.ToArray();
    }

    // create a hash
    SHA1 sha1 = SHA1.Create();
    return sha1.ComputeHash(buffer);
}

Then, you would compare the result for GetPasswordHash(username, expectedPassword, salt) to GetPasswordHash(username, givenPassword, salt).
If you implement your own user list with usernames and passwords, you might consider only saving the hash (GetPasswordHash(username, givenPassword, salt)) and comparing against the saved hash.

like image 41
configurator Avatar answered Sep 22 '22 19:09

configurator