Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
DrkWzrd opened this issue Nov 10, 2021 · 2 comments
Closed

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

DrkWzrd opened this issue Nov 10, 2021 · 2 comments
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Security

Comments

@DrkWzrd
Copy link

DrkWzrd commented Nov 10, 2021

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)

@DrkWzrd DrkWzrd added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Nov 10, 2021
@dotnet-issue-labeler dotnet-issue-labeler bot added area-System.Security untriaged New issue has not been triaged by the area owner labels Nov 10, 2021
@ghost
Copy link

ghost commented Nov 10, 2021

Tagging subscribers to this area: @bartonjs, @vcsjones, @krwq, @GrabYourPitchforks
See info in area-owners.md if you want to be subscribed.

Issue Details

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)

Author: DrkWzrd
Assignees: -
Labels:

api-suggestion, area-System.Security, untriaged

Milestone: -

@bartonjs
Copy link
Member

SecureString is obsolete and our recommendation is, essentially, to never use it. Since we're actively working on the full obsoletion plan (which, sadly, will probably never include full removal), we're not going to enhance it.

The thoughts around obsoleting this type are currently at dotnet/designs#147.

@GrabYourPitchforks GrabYourPitchforks removed the untriaged New issue has not been triaged by the area owner label Nov 10, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Dec 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Security
Projects
None yet
Development

No branches or pull requests

3 participants