SecureString to Byte [] C #

How do I get the equivalent of byte[] SecureString (which I get from PasswordBox )?

My goal is to write these bytes using CryptoStream to a file, and the Write method of this class accepts byte[] input, so I want to convert SecureString to byte[] so I can use with CryptoStream .

EDIT: I don't want to use string as it defeats the point with SecureString

+5
c # encryption wpf securestring
source share
3 answers

I changed from the original answer for unicode handling

 IntPtr unmanagedBytes = Marshal.SecureStringToGlobalAllocUnicode(password); byte[] bValue = null; try { byte* byteArray = (byte*)unmanagedBytes.GetPointer(); // Find the end of the string byte* pEnd = byteArray; char c='\0'; do { byte b1=*pEnd++; byte b2=*pEnd++; c = '\0'; c= (char)(b1 << 8); c += (char)b2; }while (c != '\0'); // Length is effectively the difference here (note we're 2 past end) int length = (int)((pEnd - byteArray) - 2); bValue = new byte[length]; for (int i=0;i<length;++i) { // Work with data in byte array as necessary, via pointers, here bValue[i] = *(byteArray + i); } } finally { // This will completely remove the data from memory Marshal.ZeroFreeGlobalAllocUnicode(unmanagedBytes); } 
+2
source share

Assuming you want to use an array of bytes and get rid of it as soon as you are done, you should encapsulate the whole operation so that it clears itself:

 public static T Process<T>(this SecureString src, Func<byte[], T> func) { IntPtr bstr = IntPtr.Zero; byte[] workArray = null; GCHandle handle = GCHandle.Alloc(workArray, GCHandleType.Pinned); try { /*** PLAINTEXT EXPOSURE BEGINS HERE ***/ bstr = Marshal.SecureStringToBSTR(src); unsafe { byte* bstrBytes = (byte*)bstr; workArray = new byte[src.Length * 2]; for (int i = 0; i < workArray.Length; i++) workArray[i] = *bstrBytes++; } return func(workArray); } finally { if (workArray != null) for (int i = 0; i < workArray.Length; i++) workArray[i] = 0; handle.Free(); if (bstr != IntPtr.Zero) Marshal.ZeroFreeBSTR(bstr); /*** PLAINTEXT EXPOSURE ENDS HERE ***/ } } 

And this is what the usage example looks like:

 private byte[] GetHash(SecureString password) { using (var h = new SHA256Cng()) // or your hash of choice { return password.Process(h.ComputeHash); } } 

No mousse, no fuss, no plain text in mind.

Keep in mind that the byte array passed to func() contains raw Unicode rendering of clear text, which should not be a problem for most cryptographic applications.

+5
source share

In this case, http://www.microsoft.com/indonesia/msdn/credmgmt.aspx you can combine it into a C # string and then convert it to an array of bytes:

 static string SecureStringToString( SecureString value ) { string s ; IntPtr p = Marshal.SecureStringToBSTR( value ); try { s = Marshal.PtrToStringBSTR( p ) ; } finally { Marshal.FreeBSTR( p ) ; } return s ; } 

or for this answer How to convert SecureString to System.String? , you can use Marshal.ReadByte and Marshal.ReadInt16 in IntPtr to get what you need.

-2
source share

All Articles