Created
January 12, 2021 14:11
-
-
Save mjs3339/41b4e90cdf14b0685d898cc15d585845 to your computer and use it in GitHub Desktop.
Secure String Helper Class
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class SecureStringHelper : IDisposable | |
{ | |
private readonly Encoding _encoding; | |
private readonly SecureString _secureString; | |
private byte[] _bytes; | |
private bool _disposed; | |
public SecureStringHelper(SecureString secureString) : this(secureString, Encoding.Default) | |
{ | |
} | |
public SecureStringHelper(SecureString secureString, Encoding encoding) | |
{ | |
if(secureString == null) | |
throw new Exception(nameof(secureString)); | |
_encoding = encoding ?? Encoding.Default; | |
_secureString = secureString; | |
} | |
public void Dispose() | |
{ | |
if(!_disposed) | |
{ | |
Destroy(); | |
_disposed = true; | |
} | |
GC.SuppressFinalize(this); | |
} | |
public static string ToString(SecureString secureStr) | |
{ | |
var Str = new NetworkCredential(string.Empty, secureStr).Password; | |
return Str; | |
} | |
public static SecureString ToSecureString(string password) | |
{ | |
if(password == null) | |
throw new Exception("Error: Password cannot be null."); | |
var securePassword = new SecureString(); | |
foreach(var c in password) | |
securePassword.AppendChar(c); | |
securePassword.MakeReadOnly(); | |
return securePassword; | |
} | |
internal unsafe byte[] ToByteArray() | |
{ | |
if(_bytes != null) | |
{ | |
_bytes.Fill(0); | |
_bytes = null; | |
} | |
var maxLength = _encoding.GetMaxByteCount(_secureString.Length); | |
var bytes = IntPtr.Zero; | |
var str = IntPtr.Zero; | |
try | |
{ | |
bytes = Marshal.AllocHGlobal(maxLength); | |
str = Marshal.SecureStringToBSTR(_secureString); | |
var chars = (char*) str.ToPointer(); | |
var bptr = (byte*) bytes.ToPointer(); | |
var len = _encoding.GetBytes(chars, _secureString.Length, bptr, maxLength); | |
_bytes = new byte[len]; | |
for(var i = 0; i < len; ++i) | |
{ | |
_bytes[i] = *bptr; | |
bptr++; | |
} | |
return _bytes; | |
} | |
finally | |
{ | |
if(bytes != IntPtr.Zero) | |
Marshal.FreeHGlobal(bytes); | |
if(str != IntPtr.Zero) | |
Marshal.ZeroFreeBSTR(str); | |
} | |
} | |
private void Destroy() | |
{ | |
if(_bytes != null) | |
{ | |
_bytes.Fill(0); | |
_bytes = null; | |
} | |
} | |
} | |
public static class SecureStringEx | |
{ | |
/// <summary> | |
/// Converts a standard string to a secure string | |
/// </summary> | |
public static SecureString ToSecureString(this string password) | |
{ | |
if(password == null) | |
throw new Exception("Error: Password cannot be null."); | |
var securePassword = new SecureString(); | |
foreach(var c in password) | |
securePassword.AppendChar(c); | |
securePassword.MakeReadOnly(); | |
return securePassword; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment