• Hello and welcome to our new forums. We upgraded our forum sites to a more robust and modern system which we hope you will enjoy. Be sure to check out your profile by clicking the button on the top right and configure your preferences, signature, time zone, avatar, etc. as you wish. If you need help with using this new forum'ware try the help link on the bottom right.

    Click here to review your account now.

declare on secure strings

TyMac

Member
Joined
Dec 7, 2014
Messages
5
Programming Experience
3-5
I need to declare a secure string a variable that is located in a text file. In Powershell this is easy:

$password = Get-content "C:\text_file_with_secure_string_in_it.txt" | convertto-securestring

How would I declare this variable correctly in C#?
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
2,202
Location
Sydney, Australia
Programming Experience
10+
How do you usually declare a variable in C#? You do this exactly the same way, but specify the type as SecureString.
 

TyMac

Member
Joined
Dec 7, 2014
Messages
5
Programming Experience
3-5
Well I can tell you that I'm doing it wrong here:

Code:
namespace DecryptStrg
{
    class Program
    {
        static void Main(string[] args)
        {
            FileInfo file = new FileInfo("C:\\path\to\\password\\file\\here\\textfile.txt");
            if (!file.Exists)
            {




                SecureString password;
                using (FileStream fs = file.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
                {
                    byte[] bytes = new byte[fs.Length];
                    int numBytesToRead = (int)fs.Length;
                    int numBytesRead = 0;
                    while (numBytesToRead > 0)
                    {
                        int n = fs.Read(bytes, numBytesRead, numBytesToRead);
                        if (n == 0)
                            break;


                        numBytesRead += n;
                        numBytesToRead -= n;
                    }
                    password = Encoding.Unicode.GetString(bytes).DecryptString();
                }
                Console.WriteLine(password.ToUnsecureString());
                Console.ReadLine();
            }
        }
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
2,202
Location
Sydney, Australia
Programming Experience
10+
You're not doing "it" wrong if "it" is what you actually asked for. You asked how to declare the variable and you're doing that just fine right here:
Code:
SecureString password;
The rest of it is inefficient and/or wrong. Firstly, why read the data from the file that way when you can simply call File.ReadAllBytes? Secondly, why read all the Bytes from a file and then use an Encoding object to convert that to a String when you can just call File.ReadAllText?

With regards to the SecureString, this line here:
Code:
password = Encoding.Unicode.GetString(bytes).DecryptString();
is passing a Byte array to Encoding.GetString, which will return a String, and then trying to call DecryptString on the result and assign the result of that to the `password` variable, which is type SecureString. For that to work, you'd have to have DecryptString declared as an extension method that extends the String type and returns a SecureString. Have you declared DecryptString like that?
 

TyMac

Member
Joined
Dec 7, 2014
Messages
5
Programming Experience
3-5
You're not doing "it" wrong if "it" is what you actually asked for. You asked how to declare the variable and you're doing that just fine right here:
Code:
SecureString password;
The rest of it is inefficient and/or wrong. Firstly, why read the data from the file that way when you can simply call File.ReadAllBytes? Secondly, why read all the Bytes from a file and then use an Encoding object to convert that to a String when you can just call File.ReadAllText?

With regards to the SecureString, this line here:
Code:
password = Encoding.Unicode.GetString(bytes).DecryptString();
is passing a Byte array to Encoding.GetString, which will return a String, and then trying to call DecryptString on the result and assign the result of that to the `password` variable, which is type SecureString. For that to work, you'd have to have DecryptString declared as an extension method that extends the String type and returns a SecureString. Have you declared DecryptString like that?
Yes:

Code:
static class Extensions
	{
		
		public static SecureString DecryptString(this string source)
		{
			if (source == null)
				return null;


			SecureString result = new SecureString();


			try
			{
				var decrypted = ProtectedData.Unprotect(Convert.FromBase64String(source), entropy, DataProtectionScope.CurrentUser);
				result = Encoding.Unicode.GetString(decrypted).ToSecureString();
			}
			catch
			{
				result = new SecureString();
			}
			return result;
		}


		public static string ToUnsecureString(this SecureString source)
		{
			if (source == null)
				return null;


			var ptr = Marshal.SecureStringToBSTR(source);


			try
			{
				return Marshal.PtrToStringBSTR(ptr);
			}
			finally
			{
				Marshal.ZeroFreeBSTR(ptr);
			}
		}
	}
Does that look correct?
 
Top Bottom