Archived Forum Post

Index of archived forum posts

Question:

Duplicate OpenSSL Commands in C#

Mar 01 '13 at 00:37

How can I duplicate the following OpenSSL process in C# using Chilkat?

I created test.key using openssl:

openssl genrsa –out test.key 2048

Then I created a self signed cert, test.pem, out of that:

openssl req –new –x509 –key test.key –out test.pem –days 1095

Now, given a file, test.txt, I want to use the private key to sign the test.txt file. I do, in openssl,

openssl rsautl –sign –inkey test.key –in test.txt –out test.bin

And output it as a base64 encoded string.

openssl base64 –in test.bin –out result.txt

The result.txt file is what we want to recreate through C# code.

Next, using the same test.key and test.pem key pair, I want to sign using SHA1 a CSR test.csr

openssl req –in test.csr –outform DER –out test.der
openssl sha1 –sign test.key –out test.signed test.der
Now I want to base64 encode the 2 files:
openssl base64 –in test.signed –out test.signed.b64 –e
openssl base64 –in test.der –out test.der.b64 –e

Test.signed.b64 and test.der.b64 are what we want to get out of Chilkat C# .Net.


Answer

This C# snippet duplicates the 1st part. It loads test.key, signs the file, and displays the base64 signature in a text box. (Note: It's not necessary to create the certificate. The test.key can be used directly.)

Chilkat.PrivateKey privKey = new Chilkat.PrivateKey();

// The key file produced by this OpenSSL command: // openssl genrsa –out test.key 2048 // is a PEM file that may be loaded into the Chilkat.PrivateKey object. bool success = privKey.LoadPemFile("c:/aaworkarea/test/test.key"); if (!success) { textBox1.Text = privKey.LastErrorText; return; }

Chilkat.Rsa rsa = new Chilkat.Rsa(); success = rsa.UnlockComponent("30-day trial"); if (!success) { textBox1.Text = rsa.LastErrorText; return; }

success = rsa.ImportPrivateKey(privKey.GetXml()); if (!success) { textBox1.Text = rsa.LastErrorText; return; }

// Read the file contents. string fileContents = System.IO.File.ReadAllText("c:/aaworkarea/test/test.txt");

// Make sure we use big-endian, which is what OpenSSL uses. rsa.LittleEndian = false;

// Sign the file contents and return the result base64 encoded: rsa.EncodingMode = "base64"; textBox1.Text = rsa.OpenSslSignStringENC(fileContents);


Answer

To duplicate this OpenSSL:

openssl sha1 –sign test.key –out test.signed test.der
openssl base64 –in test.signed –out test.signed.b64 –e
do this:

// Now for the test.der: byte[] derBytes = System.IO.File.ReadAllBytes("c:/aaworkarea/test/test.der");

// Assuming the rsa.LittleEndian property = false, and rsa.EncodingMode = "base64" textBox1.Text += rsa.SignBytesENC(derBytes, "sha1");


Answer

To base64 a binary file, read the bytes into memory and then use System.Convert.ToBase64String.


Answer

I notice that testBox1.Text is a single unterminated string.

If I copied the string into a file and ask openssl to verify it, it fails. The content is exactly the same, there's just not a LF after 64 chars.

Is that pretty much the rule to make the outfiles identical? To simply add a LF every 64 chars?


Answer

One last question, I think we missed something, how can we do the equivalent of openssl req –in test.csr –outform DER –out test.der

using your component?


Answer

Sorry I missed that. If you examine the contents of the test.csr, you'll find this:

-----BEGIN NEW CERTIFICATE REQUEST-----
MIIEgDCCA2gCAQAwfjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRQwEgYDVQQH
DAtTYW50YSBDbGFyYTEbMBkGA1UECgwSUGFsbyBBbHRvIE5ldHdvcmtzMQswCQYD
...
boQxrhckSwkSGWNuCl/T+6IY+rVUBHd9X8AizbZZs47mQxD2j6Uf0UY7Tb7UEOSR
foRSmg==
-----END NEW CERTIFICATE REQUEST-----
This is nothing more than base64-encoded DER. To convert to binary DER, just grab the base64 text between the BEGIN and END lines and decode like this:
byte[] binaryDer = System.Convert.FromBase64String(encodedDer);


Answer

PS> DER stands for Distinguished Encoding Rules. It's a standard for encoding something called ASN.1. Most of the ASN.1 you'll encounter w.r.t. PKCS related files all begin with something called an ASN.1 "Sequence", and these first few bytes when encoded in Base64 always end up "MII...". Therefore, when you see Base64 text that begins with "MII", it's highly likely it's DER encoded ASN.1.


Answer

Thanks very much.