X509 Certificates and Riijndael encryption

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.
 
M

Mattia Saccotelli

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?
 
M

Mattia Saccotelli

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?
 
N

Nicholas Paldino [.NET/C# MVP]

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.
 
N

Nicholas Paldino [.NET/C# MVP]

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.
 
M

Mattia Saccotelli

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));
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top