X509 Certificates and Riijndael encryption

  • Thread starter Thread starter Mattia Saccotelli
  • Start date Start date
M

Mattia Saccotelli

Hi
I would like to encrypt data using AES (Rijndael) algorithm, providing
as the key the key from a given certificate. Just for testing I'm using
the public key..

Shouldn't I use the private key instead of the public one?

Is there a way to get it or to use such algorithm with a specified
private key from a certificate (which may eventually be on a regular file)?

--
About the public key I did the following to get an appropriate key length:

private byte[] getKey() {
X509Certificate cer =
X509Certificate.CreateFromCertFile(@"c:\tmp\certificates\mattia.cer");
byte[] certKey = cer.GetPublicKey();
byte[] theKey = new byte[keySize / 8];
for (int i = 0; i < (keySize / 8) && i < certKey.Length; i++) {
theKey = certKey;
}

return theKey;
}

BTW I think it's not the right way to solve the problem, I can't simply
truncate the key to the needed length.
 
I managed to use the following code:

Microsoft.Web.Services.Security.X509.X509CertificateStore st =
Microsoft.Web.Services.Security.X509.X509CertificateStore.CurrentUserStore(Microsoft.Web.Services.Security.X509.X509CertificateStore.MyStore);

st.OpenRead();

MessageBox.Show(st.Certificates.Count.ToString());

if (st.Certificates.Count > 0) {
Microsoft.Web.Services.Security.X509.X509Certificate c1 =
st.Certificates[0];
MessageBox.Show(c1.GetIssuerName());
MessageBox.Show("" + c1.Key.KeySize);
}

The KeySize is 1024, how to use it in conjunction with AES? Is that
object the real private key?
 
I managed to use the following code:

Microsoft.Web.Services.Security.X509.X509CertificateStore st =
Microsoft.Web.Services.Security.X509.X509CertificateStore.CurrentUserStore(Microsoft.Web.Services.Security.X509.X509CertificateStore.MyStore);

st.OpenRead();

MessageBox.Show(st.Certificates.Count.ToString());

if (st.Certificates.Count > 0) {
Microsoft.Web.Services.Security.X509.X509Certificate c1 =
st.Certificates[0];
MessageBox.Show(c1.GetIssuerName());
MessageBox.Show("" + c1.Key.KeySize);
}

The KeySize is 1024, how to use it in conjunction with AES? Is that
object the real private key?
 
Mattia,

I don't think that what you are doing to get a key of the appropriate
length is the right way. You are just copying bytes, and that can lead to
using duplicate keys (given the right keys). If anything, set the key
length of the Rijnadel algorithm to the max (256 bits), and then perform a
hash on the public key that for that number of bits.

Hope this helps.
 
Mattia,

Something like that. There are a number of hash algorithms that you can
use. Look for any class that derives from the HashAlgorithm class in the
System.Security.Cryptography namespace.


Also, you might want to consider RC2 for your encyrption algorithm, as
it allows a key size of 1024 bits. It might be enough to handle the size of
your public key from your X.509 certificate.
 
I modified the code:

private byte[] getKey() {
X509Certificate cer =
X509Certificate.CreateFromCertFile(@"c:\tmp\certificates\mattia.cer");

byte[] certKey = cer.GetPublicKey();

PasswordDeriveBytes p = new PasswordDeriveBytes(
cer.GetPublicKeyString(),
Encoding.ASCII.GetBytes(cer.GetCertHashString()),
"SHA256",
2);

return p.GetBytes(keySize / 8);
}

does it make sense? (it works fine btw)

I would use AES because it's supposed to be a standard.

Thanks

----------------------------------

Here there are the encrypt / decrypt functions (if somebody is interested):

private byte[] Encrypt(string plainText) {
MemoryStream mStream = new MemoryStream();
SymmetricAlgorithm sAlg = SymmetricAlgorithm.Create("Rijndael");
sAlg.BlockSize = blockSize;
sAlg.KeySize = keySize;
sAlg.Padding = PaddingMode.PKCS7;

ICryptoTransform cTran = sAlg.CreateEncryptor(this.getKey(),
this.getIVector());
CryptoStream cStream = new CryptoStream(mStream, cTran,
CryptoStreamMode.Write);
StreamWriter sWriter = new StreamWriter(cStream);
sWriter.Write(plainText);
sWriter.Flush();
cStream.FlushFinalBlock();

byte[] bEncoded = new byte[mStream.Length];
mStream.Position = 0;
mStream.Read(bEncoded, 0, (int)mStream.Length);

return bEncoded;
}

private string Decrypt(byte[] cipherText) {
MemoryStream mStream = new MemoryStream();
mStream.Write(cipherText, 0, cipherText.Length);
mStream.Position = 0;

SymmetricAlgorithm sAlg = SymmetricAlgorithm.Create("Rijndael");
sAlg.BlockSize = blockSize;
sAlg.KeySize = keySize;
sAlg.Padding = PaddingMode.PKCS7;

ICryptoTransform cTran = sAlg.CreateDecryptor(this.getKey(),
this.getIVector());
CryptoStream cStream = new CryptoStream(mStream, cTran,
CryptoStreamMode.Read);
StreamReader sReader = new StreamReader(cStream);
string s = sReader.ReadToEnd();
cStream.Close();
sReader.Close();

return s;
}

// just for testing
private void button1_Click(object sender, System.EventArgs e) {
txtData.Text = Convert.ToBase64String(this.Encrypt(txtData.Text));
}

private void button2_Click(object sender, System.EventArgs e) {
txtData.Text = this.Decrypt(Convert.FromBase64String(txtData.Text));
}
 
Back
Top