4

What is best way to create SecureString(unicode encoded) from byte array? I want to store my decrypted DEK key in memory, the decryption process is made by Azure.KeyVault(api), that produce byte array as a result.

var keyBytes = client.DecryptAsync(url, keyName, keyVersion, algorithm, encryptedKeyBytes).GetAwaiter().GetResult().Result;

I have created something like that but I am not proud from that implementations.

var secureKey = new SecureString();
var secureKeyCharArray = Encoding.Unicode.GetChars(keyBytes);

for (int i = 0; i < keyBytes.Length; i++)
{
    keyBytes[i] = 0;
}

for (int i = 0; i < secureKeyCharArray.Length; i++)
{
    secureKey.AppendChar(secureKeyCharArray[i]);
    secureKeyCharArray[i] = (char)0;
}

secureKey.MakeReadOnly();

After rewriting DEK key to SecureString variable I am cleaning both array: secureKeyCharArray and keyBytes but i dont know that it is enough.

Do you know some better solutions for that case? Maybe some nuget packages? Or maybe my whole idea is wrong?

Thanks for any suggestion.

=== Edited ===============================================================

But if we focus on storing secure data in memeory, do you know any better solution than SecureString? Work with this type is a little bit dificult, for example to read key from that vartiable I am using something like that:

IntPtr unmanagedString = IntPtr.Zero;
try
{
    unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(securePassword);
    return Marshal.PtrToStringUni(unmanagedString);
}
finally
{
    Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString);
}

I dont know that it is ok for production purpose to use Marshal classes.

3
  • the code in the edit does bad things; you've just allocated a managed string with the password in it - something you want very hard to avoid: you have no control over the lifetime of that; at best you can hope that the recipient decides to use unsafe code to wipe the contents when they're done Commented Jan 19, 2018 at 11:51
  • So you think that I should read data from SecureString in different way? Or I misunderstand your answer.:D Commented Jan 19, 2018 at 12:41
  • it is an unfortunate feature of SecureString that it is virtually unusable by anything :) what I am saying is that you need to be really careful about the lifetime when you do access the content, and just returning a string doesn't make that obvious to the consumer Commented Jan 19, 2018 at 13:09

1 Answer 1

2

The most obvious problem is:

.GetAwaiter().GetResult().Result;

You should almost never do that; await would be far preferable:

var keyBytes = await client.DecryptAsync(url, keyName, keyVersion,
                                         algorithm, encryptedKeyBytes);

Using .GetAwaiter().GetResult().Result; on an incomplete awaitable operation can cause hard deadlocks. More generally, you should only try to access the result if you know (either by checking IsCompleted, or because you've awaited) that it is complete.


As for the rest: it really depends what your aim is here; and note that yes SecureString is more secure than string, but it isn't actually secure in the strong sense - a malicious user can still reverse it. It is mostly an inconvenience and something that makes it hard for memory scanners to find the data. Other than that, what you have looks OK? Note that if you want to avoid the AppendChar loop you could use fixed in an unsafe block and make use of the constructor that takes a char* and int, but that's just a performance tweak. You'd still need to erase the source array manually, of course. If you're going that route, and the password isn't large, you could actually stackalloc a block to decode into, rather than having secureKeyCharArray as an array. You would still need to manually wipe the stackalloc area when you're done.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your reply, This solutions is still in POC I will implement your advice after I will resolve all secure issues :). I have edited my question for replay on your answer, please check this out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.