1
votes

After looking at how to generate self-signed digital signatures from Creating a self-signed certificate in C#, I can call CreateSelfSignCertificatePfx and get PXF data in a byte array back, which can then be used within an X509Certificate2 object to sign and verify. Example...

byte[] pfx = Certificate.CreateSelfSignCertificatePfx("O=Company,CN=Firstname,SN=Lastname", DateTime.Now, DateTime.Now.AddYears(1), "password");

X509Certificate2 cert = new X509Certificate2(pfx, "password");
byte[] publicBytes = cert.RawData;

RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey;
byte[] signedData = rsa.SignData(new System.Text.UTF8Encoding().GetBytes("Test"), new SHA1CryptoServiceProvider());

RSACryptoServiceProvider rsa2 = (RSACryptoServiceProvider)new X509Certificate2(publicBytes).PublicKey.Key;

bool verified = rsa2.VerifyData(new System.Text.UTF8Encoding().GetBytes("Test"), new SHA1CryptoServiceProvider(), signedData);

This works. My concern though is the original bytes, byte[] pfx from above, need to be stored in a DB (to sign stuff). The question becomes, how secure are the bytes in this format? I know you need the password to construct the new X509Certificate2 with a private key, but in a general sense, how secure are the bytes without the password? I have no problems encrypting these bytes as an added layer, but is that necessary?

According to X509Certificate2.X509Certificate2(Byte[], String) Constructor

Calling this constructor with the correct password decrypts the private key and saves it to a key container.

I just want to ensure the private key is safe without the password.

3

3 Answers

1
votes

In my eyes the question is not whether you should put the "bytes" in the database, but more, would you put the file with the private key in your file system.

In the way you're doing it, it's essentially the same thing. You're just storing the bytes that make up the cert file.

I may be failing to understand the difference here, but they bytes and the file are essentially the same thing, the only difference being the fact that one has to gain access to the db to get them.

0
votes

Use a smartcard or token to store your private key.

UPDATE: The Pvt key can be accessed by anyone who can access the machine.

0
votes

The private keys in a PFX (PKCS#12) are stored encrypted, which is of course what the password is for. Not all of a PFX is encrypted, the structural pieces stay plaintext to contain metadata about the contents (like what encryption algorithm was used).

Based on inspecting the file, as of Windows 7 the private keys are encrypted using 3-key (168-bit) 3DES. The key is derived via a complex formula involving your password; there's nothing saved in the file which gives any indication as to what your password was, how long it was, et cetera.

The password is usually proven correct by the addition of a MAC on the contents, which uses the same password for its key derivation function. In the possible case of the MAC password and the encryption password being different (which I've personally never seen) the password is verified by the structural information in the encrypted payload.

DES' weakness mainly lay in the small keysize, it's easily brute forcable today. A 3-key 3DES key has 112 more semantic bits than a (1)DES key, making it take 2^112 (~5 x 10^33) times longer to break.

So, at the end of the day, the private key is cryptographically sound. But like anything with a password-based input, if you use a bad password that is easily guessed then it can be cracked by brute force.