views:

742

answers:

4

How do I sign a file using .NET and how do I then validate that the generated key is a valid one once I read it?

My goal is to have a text file with some values and a generated key. I then want to be able to check that generated key in the file to make no one has tampered with the values in the file once I sent the file to a customer.

Update: Found it here with some help from the answers.

A: 

You have two possibilities:

  • Once is on project properties on the Sign option.
  • The second is modify the AssemblyInfo.cs file and add the commands to use the sn generated: [assembly: AssemblyKeyFile("..\\..\\SN_Generated.snk")]
jaloplo
I don't want to sign a assembly. I want to generate a value in a file to avoid tampering with the values in that file.
Riri
A: 

The definitive reference at MSDN

and

Assembly Signing for Dummies

Cerebrus
I don't want to sign a assembly. I want to generate a value in a file to avoid tampering with the values in that file.
Riri
+2  A: 

If you want to sign a assembly, jaloplo gave the solution.

If you want to sign some files created by your program, have a look at the DSACryptoServiceProvider class in the System.Security.Cryptography namespace.

Daniel Brückner
+1  A: 

Try this:

class Program
{
    static byte[] Sign(string message, RSAParameters key)
    {
        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
        rsa.ImportParameters(key);

        byte[] toSign = Encoding.Unicode.GetBytes(message);
        return rsa.SignData(toSign, "SHA1");
    }

    static bool Verify(string message, byte[] signature, RSAParameters key)
    {
        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
        rsa.ImportParameters(key);

        byte[] toVerify = Encoding.Unicode.GetBytes(message);
        return rsa.VerifyData(toVerify, "SHA1", signature);
    }

    static void Main(string[] args)
    {
        string message = "Let's sign this message.";

        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); // Creates a new RANDOM key.
        RSAParameters privatekey = rsa.ExportParameters(true);
        RSAParameters publickey = rsa.ExportParameters(false);

        byte[] signature = Sign(message, privatekey);

        if (Verify(message, signature, publickey))
        {
            Console.WriteLine("It worked!");
        }
    }
}

It's important to note that a new public/private keypair is generated everytime you start this program. In order to do what you want, you'll want to save the public/private keypair before using it at both ends. Your public key is the only thing you need to verify, so your private key will not be published to the client.

You might want to take a look at ExportParameters or ExportCspBlob to accomplish saving/loading the public/private keypair.

Dave Van den Eynde