Sample code for 30+ languages & platforms
Unicode C

Duplicate openssl req -newkey rsa:2048 -nodes -keyout mydomain.pem -out mydomain.csr

See more OpenSSL Examples

Demonstrates how to duplicate this OpenSSL command:
openssl req -newkey rsa:2048 -nodes -keyout mydomain.pem -out mydomain.csr

This command creates 2 files:

  1. mydomain.csr: this is the file to send to DigiCert or Let's Encrypt (or any other CA)
  2. mydomain.pem: this is the private key of the domain.

The second file is needed to pair with the certificate that will later be received from the CA.

Chilkat Unicode C Downloads

Unicode C
#include <C_CkRsaW.h>
#include <C_CkPrivateKeyW.h>
#include <C_CkXmlW.h>
#include <C_CkAsnW.h>
#include <C_CkBinDataW.h>

void ChilkatSample(void)
    {
    BOOL success;
    HCkRsaW rsa;
    HCkPrivateKeyW privKey;
    HCkXmlW privKeyXml;
    const wchar_t *keyModulus;
    HCkAsnW asnRoot;
    HCkAsnW asnCertReqInfo;
    HCkAsnW asnCertSubject;
    HCkAsnW asnTemp;
    HCkAsnW asnPubKeyInfo;
    HCkAsnW asnPubKeyAlgId;
    HCkAsnW asnRsaKey;
    const wchar_t *rsaKeyDerBase64;
    HCkBinDataW bdDer;
    HCkBinDataW bdSig;
    HCkAsnW asnAlgId;
    const wchar_t *csrBase64;

    success = FALSE;

    // This example requires the Chilkat API to have been previously unlocked.
    // See Global Unlock Sample for sample code.

    rsa = CkRsaW_Create();

    // Generate a 2048-bit key.  Chilkat RSA supports
    // key sizes ranging from 512 bits to 8192 bits.
    privKey = CkPrivateKeyW_Create();
    success = CkRsaW_GenKey(rsa,2048,privKey);
    if (success == FALSE) {
        wprintf(L"%s\n",CkRsaW_lastErrorText(rsa));
        CkRsaW_Dispose(rsa);
        CkPrivateKeyW_Dispose(privKey);
        return;
    }

    CkRsaW_UsePrivateKey(rsa,privKey);

    // Save the private key to unencrypted PKCS8 PEM
    success = CkPrivateKeyW_SavePkcs8PemFile(privKey,L"mydomain.pem");

    // (alternatively) Save the private key to encrypted PKCS8 PEM
    success = CkPrivateKeyW_SavePkcs8EncryptedPemFile(privKey,L"myPassword",L"mydomain_enc.pem");

    // We'll need the private key's modulus for the CSR.
    // The modulus is not something that needs to be protected.  Most people don't realize
    // that a public key is actually just a subset of the private key.  The public parts of
    // an RSA private key are the modulus and exponent.  The exponent is always 65537.
    privKeyXml = CkXmlW_Create();
    success = CkXmlW_LoadXml(privKeyXml,CkPrivateKeyW_getXml(privKey));

    // Get the modulus in base64 format:
    keyModulus = CkXmlW_getChildContent(privKeyXml,L"Modulus");

    // --------------------------------------------------------------------------------
    // Now build the CSR using Chilkat's ASN.1 API.
    // The keyModulus will be embedded within the ASN.1.

    // A new ASN.1 object is automatically a SEQUENCE.
    // Given that the CSR's root item is a SEQUENCE, we can use
    // this as the root of our CSR.
    asnRoot = CkAsnW_Create();

    // Beneath the root, we have a SEQUENCE (the certificate request info), 
    // another SEQUENCE (the algorithm identifier), and a BITSTRING (the signature data)

    success = CkAsnW_AppendSequence(asnRoot);
    success = CkAsnW_AppendSequence(asnRoot);

    // ----------------------------------
    // Build the Certificate Request Info
    // ----------------------------------
    asnCertReqInfo = CkAsnW_GetSubItem(asnRoot,0);
    success = CkAsnW_AppendInt(asnCertReqInfo,0);

    // Build the Subject part of the Certificate Request Info
    asnCertSubject = CkAsnW_AppendSequenceR(asnCertReqInfo);

    // Add each subject part..
    asnTemp = CkAsnW_AppendSetR(asnCertSubject);
    success = CkAsnW_AppendSequence2(asnTemp);
    // AppendSequence2 updates the internal reference to the newly appended SEQUENCE.
    // The OID and printable string are added to the SEQUENCE.
    success = CkAsnW_AppendOid(asnTemp,L"2.5.4.6");
    success = CkAsnW_AppendString(asnTemp,L"printable",L"US");
    CkAsnW_Dispose(asnTemp);

    asnTemp = CkAsnW_AppendSetR(asnCertSubject);
    success = CkAsnW_AppendSequence2(asnTemp);
    success = CkAsnW_AppendOid(asnTemp,L"2.5.4.8");
    success = CkAsnW_AppendString(asnTemp,L"utf8",L"Utah");
    CkAsnW_Dispose(asnTemp);

    asnTemp = CkAsnW_AppendSetR(asnCertSubject);
    success = CkAsnW_AppendSequence2(asnTemp);
    success = CkAsnW_AppendOid(asnTemp,L"2.5.4.7");
    success = CkAsnW_AppendString(asnTemp,L"utf8",L"Lindon");
    CkAsnW_Dispose(asnTemp);

    asnTemp = CkAsnW_AppendSetR(asnCertSubject);
    success = CkAsnW_AppendSequence2(asnTemp);
    success = CkAsnW_AppendOid(asnTemp,L"2.5.4.10");
    success = CkAsnW_AppendString(asnTemp,L"utf8",L"DigiCert Inc.");
    CkAsnW_Dispose(asnTemp);

    asnTemp = CkAsnW_AppendSetR(asnCertSubject);
    success = CkAsnW_AppendSequence2(asnTemp);
    success = CkAsnW_AppendOid(asnTemp,L"2.5.4.11");
    success = CkAsnW_AppendString(asnTemp,L"utf8",L"DigiCert");
    CkAsnW_Dispose(asnTemp);

    asnTemp = CkAsnW_AppendSetR(asnCertSubject);
    success = CkAsnW_AppendSequence2(asnTemp);
    success = CkAsnW_AppendOid(asnTemp,L"2.5.4.3");
    success = CkAsnW_AppendString(asnTemp,L"utf8",L"example.digicert.com");
    CkAsnW_Dispose(asnTemp);

    CkAsnW_Dispose(asnCertSubject);

    // Build the Public Key Info part of the Certificate Request Info
    asnPubKeyInfo = CkAsnW_AppendSequenceR(asnCertReqInfo);

    asnPubKeyAlgId = CkAsnW_AppendSequenceR(asnPubKeyInfo);
    success = CkAsnW_AppendOid(asnPubKeyAlgId,L"1.2.840.113549.1.1.1");
    success = CkAsnW_AppendNull(asnPubKeyAlgId);
    CkAsnW_Dispose(asnPubKeyAlgId);

    // The public key itself is a BIT STRING, but the bit string is composed of ASN.1
    // for the RSA public key.  We'll first build the RSA ASN.1 for the public key
    // (containing the 2048 bit modulus and exponent), and encoded it to DER, and then add
    // the DER bytes as a BIT STRING (as a sub-item of asnPubKeyInfo)

    // This is already a SEQUENCE..
    asnRsaKey = CkAsnW_Create();

    // The RSA modulus is a big integer.
    success = CkAsnW_AppendBigInt(asnRsaKey,keyModulus,L"base64");
    success = CkAsnW_AppendInt(asnRsaKey,65537);

    rsaKeyDerBase64 = CkAsnW_getEncodedDer(asnRsaKey,L"base64");

    // Now add the RSA key DER as a BIT STRING.
    success = CkAsnW_AppendBits(asnPubKeyInfo,rsaKeyDerBase64,L"base64");
    CkAsnW_Dispose(asnPubKeyInfo);

    // The last part of the certificate request info is an empty context-specific constructed item
    // with a tag equal to 0.
    success = CkAsnW_AppendContextConstructed(asnCertReqInfo,0);

    // Get the DER of the asnCertReqInfo.  
    // This will be signed using the RSA private key.
    bdDer = CkBinDataW_Create();
    success = CkAsnW_WriteBd(asnCertReqInfo,bdDer);

    // Add the signature to the ASN.1
    bdSig = CkBinDataW_Create();
    success = CkRsaW_SignBd(rsa,bdDer,L"SHA1",bdSig);
    success = CkAsnW_AppendBits(asnRoot,CkBinDataW_getEncoded(bdSig,L"base64"),L"base64");

    CkAsnW_Dispose(asnCertReqInfo);

    // ----------------------------------
    // Finally, add the algorithm identifier, which is the 2nd sub-item under the root.
    // ----------------------------------
    asnAlgId = CkAsnW_GetSubItem(asnRoot,1);
    success = CkAsnW_AppendOid(asnAlgId,L"1.2.840.113549.1.1.5");
    success = CkAsnW_AppendNull(asnAlgId);
    CkAsnW_Dispose(asnAlgId);

    // Write the CSR to a DER encoded binary file:
    success = CkAsnW_WriteBinaryDer(asnRoot,L"qa_output/mydomain.csr");
    if (success == FALSE) {
        wprintf(L"%s\n",CkAsnW_lastErrorText(asnRoot));
        CkRsaW_Dispose(rsa);
        CkPrivateKeyW_Dispose(privKey);
        CkXmlW_Dispose(privKeyXml);
        CkAsnW_Dispose(asnRoot);
        CkAsnW_Dispose(asnRsaKey);
        CkBinDataW_Dispose(bdDer);
        CkBinDataW_Dispose(bdSig);
        return;
    }

    // It is also possible to get the CSR in base64 format:
    csrBase64 = CkAsnW_getEncodedDer(asnRoot,L"base64");

    wprintf(L"Base64 CSR:\n");
    wprintf(L"%s\n",csrBase64);


    CkRsaW_Dispose(rsa);
    CkPrivateKeyW_Dispose(privKey);
    CkXmlW_Dispose(privKeyXml);
    CkAsnW_Dispose(asnRoot);
    CkAsnW_Dispose(asnRsaKey);
    CkBinDataW_Dispose(bdDer);
    CkBinDataW_Dispose(bdSig);

    }