Skip to main content

Converts a plain String value to a SecureString value, and a SecureString value to a String value.

using System;
using System.Runtime.InteropServices;
using System.Security;

namespace ConsoleTester
{
    public static class Extensions
    {
        /// <summary>
        /// Converts the string to an unsecure string.
        /// </summary>
        /// <remarks>
        /// How to properly convert SecureString to String:
        /// https://blogs.msdn.microsoft.com/fpintos/2009/06/12/how-to-properly-convert-securestring-to-string/
        /// </remarks>
        /// <param name="securePassword">The secure password.</param>
        /// <returns>The specified SecureString as a String.</returns>
        public static string ConvertToUnsecureString(this SecureString securePassword)
        {
            if (securePassword == null)
            {
                throw new ArgumentNullException("securePassword");
            }

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

        /// <summary>
        /// Converts to secure string.
        /// </summary>
        /// <remarks>
        /// How to properly convert SecureString to String:
        /// https://blogs.msdn.microsoft.com/fpintos/2009/06/12/how-to-properly-convert-securestring-to-string/
        /// IMPORTANT: The project must have "Allow unsafe code"
        /// enabled for this code run.
        /// </remarks>
        /// <param name="password">The password.</param>
        /// <returns>The specified String as a SecureString.</returns>
        public static SecureString ConvertToSecureString(this string password)
        {
            if (password == null)
            {
                throw new ArgumentNullException("password");
            }

            unsafe
            {
                fixed (char* passwordChars = password)
                {
                    var securePassword = new SecureString(passwordChars, password.Length);
                    securePassword.MakeReadOnly();
                    return securePassword;
                }
            }
        }
    }
}