I have a function that generates a BouncyCastle RSA key pair. I need to encrypt the private key and then store the encrypted private and public keys into separate SQL2008 database fields.
I am using the following to get the keypair:
private static AsymmetricCipherKeyPair createASymRandomCipher()
{
RsaKeyPairGenerator r = new RsaKeyPairGenerator();
r.Init(new KeyGenerationParameters(new SecureRandom(), 1024));
AsymmetricCipherKeyPair keys = r.GenerateKeyPair();
return keys;
}
This is returning the keys fine, but I am not sure how I can then encrypt the private key and subsequently store it in the database.
This is what I am currently using the encrypt the data (incorrectly?):
public static byte[] encBytes2(AsymmetricKeyParameter keyParam, byte[] Key, byte[] IV)
{
MemoryStream ms = new MemoryStream();
Rijndael rjdAlg = Rijndael.Create();
rjdAlg.Key = Key;
rjdAlg.IV = IV;
CryptoStream cs = new CryptoStream(ms, rjdAlg.CreateEncryptor(), CryptoStreamMode.Write);
byte[] keyBytes = System.Text.Encoding.Unicode.GetBytes(keyParam.ToString());
cs.Write(keyBytes, 0, keyBytes.Length);
cs.Close();
byte[] encryptedData = ms.ToArray();
return encryptedData;
}
Obviously the keyBytes setting where I am converting keyParam.ToString() is not correct as it only converts the KeyParameter name, not the actual value. I am submitting to this function the previous key pair return of keys.Private.
The other question is as I am not encrypting the Public Key what format should I be storing this in the SQL2008 database, nvarchar(256) or other?
Any help would be greatly appreciated.
For reasons that should be clear, default (and perhaps inadvertent) serialization does not play well with private keys which should only be written out in very limited situations.
BouncyCastle has support for PKCS#8, which is the relevant standard for “serializing” private keys. There are ASN.1 structures called PrivateKeyInfo and EncryptedPrivateKeyInfo. Since they are in ASN.1 there are standard ways to serialize/deserialize them. As the name suggests, one stores the key in plaintext, the other encrypts the key based on a password.
For the public keys – these would not ordinarily be encrypted. BC supports the X.509 standard format of SubjectPublicKeyInfo for serializing them.
In the C# build, the high-level classes to look at would be: