Skip to content

[API Proposal]: Add extensions to SecureString to improve it use. #61426

@DrkWzrd

Description

@DrkWzrd

Background and motivation

In advance, sorry for my english.

SecureString is right now (and has been) a sorta of not useful API because -in a developer point of view- any management of it requires to use Marshal API in order to make something with it.
It is useful in logging scenarios (avoiding to expose the password) and reducing the time the password is in plaintext. And avoids some attacker discover the password by some dump file or something like that.

As I say, the class is "useful in some scenarios, but not "easy" to use when developing the software (as commented if you need to work with the data inside the SecureString you need to be concerned about Marshaling and free the data, etc...)

It will be useful to include some fast-to-use and "not-error-prone" APIs in an extension way, using the current cryptography namespace classes

API Proposal

namespace System.Collections.Generic
{
    //names are dumb placeholders
    public class SecureStringExtensions
    {
         public static byte[] Digest(this SecureString secureString, HashAlgorithm hashAlgorithm); //"I don't care about the password, I only need the hash...

        public static byte[] Encrypt(this SecureString secureString, SymmetricAlgorithm symmetricAlgorithm); //"I'd like to be capable of know the password if I require it."

        public static byte[] GetPbkdf2Key(this SecureString secureString, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm, int keyLength); // "Let's do it right, I don't need the password, but a key derived from it"
    }

   public class SecureStringHelpers
   {
        public static SecureString DecryptToSecureString(byte[] encryptedData, SymmetricAlgorithm symmetricAlgorithm); //The counter-part of the encrypt method.
   }
}

API Usage

var passwordBoxSecureString = ....;
//I get my SecureString from... WPF PasswordBox, for example
//And i want to store it or make something with it, but I don't need the password as is.
byte[] randomSalt = ..., //I get some random bytes.
int keyByteLength = 32;
var derivedKey = passwordBoxSecureString.GetPbkdf2Key(randomSalt, 20000, HashAlgorithmName.SHA512, keyByteLength);
//now I can use the derivedKey array and discard the securestring "safely".

//other scenario
var hashAlg = SHA512.Create();
var hashedPass = passwordBoxSecureString.Digest(hashAlg);
//I can use hashedPass now and discard the securestring.

Alternative Designs

Instead of use SymmetricAlgorithm/HashAlgorithm, we can use directly ICryptoTransform interface, but this can make the user can put as argument a decryptor instead of an encryptor.

I'm not sure but... can Asymmetric cryptography coexist too?

Risks

At the end, you are working with the bytes of a hashed password, and this can have caveats.
Furthermore I'm sure there are so many hard points I can't see (I'm not a cryptography expert)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions