Archived Forum Post

Index of archived forum posts


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.


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


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


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


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?


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?


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

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


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.


Thanks very much.