Take the 2-minute tour ×

I have an issue where I need to be able to have a compiled exe ( .net 3.5 c# ) that I will make copies of to distribute that will need to change a key for example before the exe is sent out.

I cannot compile each time a new exe is needed. This is a thin client that will be used as part of a registration process.

Is it possible to add a entry to a resource file with a blank value then when a request comes in have another application grab the blank default thin client, copy it, populate the blank value with the data needed.

If yes how? If no do you have any ideas? I have been scratching my head for a few days now and the limitation as due to the boundaries I am required to work in.

The other idea I has was to inject the value into a method, which I have no idea how I would even attempt that.


share|improve this question
What is the purpose of this? Knowing that might help us help you better. –  Robert Harvey Apr 30 '10 at 6:06
Hello Robert, I need to distribute a thin client exe to x users. This client however need to be able to have a key injected on the fly before it is sent. Compiling on demand will not work. Every client sent out will have its own unique identifier associated with it. I cant use an app.config file as the file must be self contained ( another requirement ) hence I started looking at resource file as the key must be embedded. Thanks. –  nitefrog Apr 30 '10 at 7:17
Will the file have to be signed? –  Lasse V. Karlsen Apr 30 '10 at 13:46
I think it might be, but if you have an option I am all ears. Thanks. –  nitefrog Apr 30 '10 at 16:53

4 Answers 4

up vote 4 down vote accepted

Convert the assembly to IL, do a textual search and replace, recompile the IL to an assembly again. Use the standard tools from the .NET SDK.

share|improve this answer
Dan and Amry I just posted this question: stackoverflow.com/questions/2749113/… I am going to take the ildasm and ilasm approach, but do you know how to automate this without having to command line it using process.start? –  nitefrog May 1 '10 at 6:42

Instead of embedding the key in the assembly, put it in the app.config file (or another file delivered with the application) and prevent your application from running if the key is not present and valid. To protect it against modification by users, also add an RSA signature the config file.

This code could be used to generate XML containing your key.

public static void Main()

public static Byte[] Transform(Byte[] bytes, ICryptoTransform xform)
   using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
      using (CryptoStream cstream = new CryptoStream(stream, xform, CryptoStreamMode.Write))
         cstream.Write(bytes, 0, bytes.Length);
         return stream.ToArray();

public static string GenerateKey()
   RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
   // This is the private key and should never be shared.
   // Generate your own with RSA.Create().ToXmlString(true).
   String rsaPrivateKey = "<RSAKeyValue><Modulus>uPCow37yEzlKQXgbqO9E3enSOXY1MCQB4TMbOZyk9eXmc7kuiCMhJRbrwild0LGO8KE3zci9ETBWVVSJEqUqwtZyfUjvWOLHrf5EmzribtSU2e2hlsNoB2Mu11M0SaGd3qZfYcs2gnEnljfvkDAbCyJhUlxmHeI+35w/nqSCjCk=</Modulus><Exponent>AQAB</Exponent><P>4SMSdNcOP0qAIoT2qzODgyl5yu9RubpIU3sSqky+85ZqJHXLUDjlgqAZvT71ROexJ4tMfMOgSWezHQwKWpz3sw==</P><Q>0krr7cmorhWgwCDG8jmzLMo2jafAy6tQout+1hU0bBKAQaPTGGogPB3hTnFIr84kHcRalCksI6jk4Xx/hiw+sw==</Q><DP>DtR9mb60zIx+xkdV7E8XYaNwx2JeUsqniwA3aYpmpasJ0N8FhoJI9ALRzzp/c4uDiuRNJIbKXyt6i/ZIFFH0qw==</DP><DQ>mGCxlBwLnhkN4ind/qbQriPYY8yqZuo8A9Ggln/G/IhrZyTOUWKU+Pqtx6lOghVdFjSxbapn0W8QalNMFGz7AQ==</DQ><InverseQ>WDYfqefukDvMhPHqS8EBFJFpls/pB1gKsEmTwbJu9fBxN4fZfUFPuTnCIJsrEsnyRfeNTAUFYl3hhlRYZo5GiQ==</InverseQ><D>qB8WvAmWFMW67EM8mdlReI7L7jK4bVf+YXOtJzVwfJ2PXtoUI+wTgH0Su0IRp9sR/0v/x9HZlluj0BR2O33snQCxYI8LIo5NoWhfhkVSv0QFQiDcG5Wnbizz7w2U6pcxEC2xfcoKG4yxFkAmHCIkgs/B9T86PUPSW4ZTXcwDmqU=</D></RSAKeyValue>";

   String signedData = "<SignedData><Key>Insert your key here</Key></SignedData>";
   Byte[] licenseData = System.Text.Encoding.UTF8.GetBytes(signedData);
   Byte[] sigBytes = rsa.SignData(licenseData, new SHA1CryptoServiceProvider());
   String sigText = System.Text.Encoding.UTF8.GetString(Transform(sigBytes, new ToBase64Transform()));
   System.Text.StringBuilder sb = new StringBuilder();
   using (System.Xml.XmlWriter xw = System.Xml.XmlTextWriter.Create(sb))
      xw.WriteElementString("Signature", sigText);
   return sb.ToString();

Example output from this code:

    <Key>Insert your key here</Key>

Then you can use code like this to verify it. You never have to distribute the private key:

public static Boolean CheckLicenseSignature(String licXml)
      System.Xml.XmlDocument xd = new System.Xml.XmlDocument();
      String licSig = xd.SelectSingleNode("/License/Signature").InnerText;
      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
      Byte[] licenseData = System.Text.Encoding.UTF8.GetBytes(xd.SelectSingleNode("/License/SignedData").OuterXml);
      return rsa.VerifyData(licenseData, new SHA1CryptoServiceProvider(), Transform(System.Text.Encoding.UTF8.GetBytes(licSig), new FromBase64Transform()));
   catch (System.Xml.XmlException ex)
      return false;
   catch (InvalidOperationException ex)
      return false;
share|improve this answer
Again the file must be self contained. I cannot have any dependent files, but this is a pretty awesome solution if I could have another file to ride along. Also the key must be able to be read as encryption isn't needed. There is another process in the security that will lock down security. I just need to have a unique identifier associated with the exe and it needs to be embedded with each exe I send out. –  nitefrog Apr 30 '10 at 18:40
I thought you might be solving the wrong problem because I think in many cases the app's config file is automatically transported with the executable. And there are also ways of packaging multiple files into one if necessary. But if those problems are harder to deal with than the solution you've accepted, certainly take the path of least resistance. –  BlueMonkMN May 2 '10 at 12:37
Also, the key does not get encrypted by this code. The entire XML is plain text, and only the signature added to the end is incomprehensible. –  BlueMonkMN May 2 '10 at 12:38

From within the capability of the .NET code itself, I'm not sure if this is doable. But it is possible to dynamically generate a .NET DLL which contains some key that can be referred from the main application. That is, if you wouldn't mind a second file in the distribution.

Or if you don't mind to use Ildasm to disassemble the .exe, change the key, then use Ilasm to reassemble, then you can do something to automate that.

share|improve this answer
If you convert to il and convert back will that cause any issues with signing the exe once it is converted back. The process, needs to be automated. For the life of me I cannot get UpdateResource to work. It modifies the file but does not overwrite the Name value... –  nitefrog Apr 30 '10 at 7:54
You can sign the exe when reassembling it using the ilasm /key=keyfile argument. –  Amry Apr 30 '10 at 8:01
I just tried and created an IL, the issue is that the resource file info does not show anywhere. I can see the name but not the value. Has anyone gotten UpdateResource to work? –  nitefrog Apr 30 '10 at 8:19

What comes to my mind, but not tried yet: Create a default String in your program, for example as

static public string regGuid = "yourguidhere";

Then, search the compiled EXE with any decent hex editor. If you find the string, replace it with another test. If you still can execute the program, you could try to automate this process and voila! Here you are.

share|improve this answer
I don't know if unsigned assemblies have any sort of checksum, but I think that will fail for signed assemblies, as the signature will no longer be valid. –  Jon Skeet Apr 30 '10 at 6:12
Not to mention all the fun if the length changes... –  Marc Gravell Apr 30 '10 at 6:19
That is the problem, the key cannot be guaranteed to be the same length every time. Hence a variable length key. –  nitefrog Apr 30 '10 at 7:19
@nitefrong: As long as you allocate more space than the key will need (e.g. 40 characters and just pad the key out with spaces when you insert it), that isn't an issue. But signing will be. –  Jason Williams Apr 30 '10 at 7:23

Your Answer


