15

Here's my current situation - I have an application that compiles C# code taken in as a string, using CodeDom. I have a SecureString that stores a password and I was wondering if there would be any way to pass that SecureString variable into the compiled code as a SecureString?

Here is some example code:

SecureString securePassword = getSecurePass();

string codeString =
        @"using System;
        using System.Security;

        namespace SomeProgram
        {
            class MyClass
            {
                static void Main(string[] args)
                {
                    SecureString securePass = new SecureString();
                    // somehow set this equal to the securePassword variable
                }
            }
        }";


// Compiler Code
CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");
string outFile = "output.exe"; 

System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = true;
parameters.OutputAssembly = outFile;
CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, codeString);

I can't find a way to do this and I imagine that this isn't actually possible and instead I should possibly just store the password in an encrypted file and read it from that?

Jake
  • 205
  • 1
  • 8
  • 1
    You're writing out an exe, so you anyway want to embed the password in it in a serialized form. It's not like you're providing a value to a running program. – GSerg Jul 28 '15 at 16:31
  • 1
    (Which might be conveniently done by [adding a resource](http://stackoverflow.com/q/13666956/11683) to your assembly that contains an encrypted blob). – GSerg Jul 28 '15 at 16:40
  • @GSerg That is a genius idea, are resources built into the actual EXE or would they be stored separately (in a separate file), because if they're stored separately then I might as well encrypt the string and output it to a txt file? – Jake Jul 28 '15 at 17:02
  • [Yes they do](https://msdn.microsoft.com/en-us/library/system.codedom.compiler.compilerparameters.embeddedresources%28v=vs.110%29.aspx), because they are `EmbeddedResources`. There are also `LinkedResources`. – GSerg Jul 28 '15 at 17:08

2 Answers2

4

I think you're confused about the concepts. You're trying to compile the password into an exe file, and you think that SecureString will keep your password secure. That's not what the SecureString is for. Read the documentation:

(SecureString) Represents text that should be kept confidential, such as by deleting it from computer memory when no longer needed.

SecureString will only protect your in-memory password by 1) encrypting it while it is in the memory so no other apps can sniff it, and 2) removing it from the memory once you're done with it.

If you compile your password into an exe, a hacker can easily get it from there even if it is encrypted. In fact, getting it from the exe is much easier than getting it from the memory. Encrypting it will only make it a bit harder, but a skilled hacker can still decrypt it after finding the key. The suggestion given by Gseg to compile it as an embedded resource and your suggestion of encrypting it in a text file, both will have the same issue.

It all comes down to the encryption key, where is it stored? If you store it in the exe file (because you need your app to be able to decrypt it), then the hacker will be able to find the key and use it to decrypt your password. You will need to store it outside the exe in a way that is not reachable by the hacker. So the real issue that you need to think about is: Where to store the encryption key so the app can read it, but the hacker cannot?.

Now, when your app retrieves the key, then now you can decrypt the password to a SecureString variable to protect it while it is in memory and remove it afterwards.

Racil Hilan
  • 24,690
  • 13
  • 50
  • 55
1

Well all you need is to figure a way to change SecureString to System.String.

Already answered here : How to convert SecureString to System.String?

string codeString =
    String.Format(@"using System;
    using System.Security;

    namespace SomeProgram
    {
        class MyClass
        {
            static void Main(string[] args)
            {
                SecureString securePass = new SecureString();
                {0} // use it the way u like
            }
        }
    }", SecureStringToString(securePassword));
Community
  • 1
  • 1
Parimal Raj
  • 20,189
  • 9
  • 73
  • 110
  • 3
    I believe the OP wanted to keep the string secure in the process. – GSerg Jul 28 '15 at 16:35
  • 1
    I already have a method that can do that but isn't hardcoding a password a very bad idea? (and yes, like GSerg said, keeping the password in a SecureString would be ideal) – Jake Jul 28 '15 at 16:36
  • 1
    @PhilJones- it's not possible, you need something that is secure in memory and then it is needed in raw format to be secure again. – Parimal Raj Jul 28 '15 at 17:25