Sample code for 30+ languages & platforms
Pascal (Lazarus/Delphi)

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 Pascal (Lazarus/Delphi) Downloads

Pascal (Lazarus/Delphi)
program ChilkatDemo;

// Demonstrates using the Chilkat Pascal wrapper via the C bridge DLL.
// Builds as a console application under Lazarus (FPC) or Delphi.

{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}
{$APPTYPE CONSOLE}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  SysUtils,
  CkDllLoader,
  Chilkat.BinData,
  Chilkat.Asn,
  Chilkat.PrivateKey,
  Chilkat.Rsa,
  Chilkat.Xml;

// ---------------------------------------------------------------------------

procedure RunDemo;
var
  success: Boolean;
  rsa: TRsa;
  privKey: TPrivateKey;
  privKeyXml: TXml;
  keyModulus: string;
  asnRoot: TAsn;
  asnCertReqInfo: TAsn;
  asnCertSubject: TAsn;
  asnTemp: TAsn;
  asnPubKeyInfo: TAsn;
  asnPubKeyAlgId: TAsn;
  asnRsaKey: TAsn;
  rsaKeyDerBase64: string;
  bdDer: TBinData;
  bdSig: TBinData;
  asnAlgId: TAsn;
  csrBase64: string;

begin
  success := False;

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

  rsa := TRsa.Create;

  //  Generate a 2048-bit key.  Chilkat RSA supports
  //  key sizes ranging from 512 bits to 8192 bits.
  privKey := TPrivateKey.Create;
  success := rsa.GenKey(2048,privKey);
  if (success = False) then
    begin
      WriteLn(rsa.LastErrorText);
      Exit;
    end;

  rsa.UsePrivateKey(privKey);

  //  Save the private key to unencrypted PKCS8 PEM
  success := privKey.SavePkcs8PemFile('mydomain.pem');

  //  (alternatively) Save the private key to encrypted PKCS8 PEM
  success := privKey.SavePkcs8EncryptedPemFile('myPassword','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 := TXml.Create;
  success := privKeyXml.LoadXml(privKey.GetXml());

  //  Get the modulus in base64 format:
  keyModulus := privKeyXml.GetChildContent('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 := TAsn.Create;

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

  success := asnRoot.AppendSequence();
  success := asnRoot.AppendSequence();

  //  ----------------------------------
  //  Build the Certificate Request Info
  //  ----------------------------------
  asnCertReqInfo := asnRoot.GetSubItem(0);
  success := asnCertReqInfo.AppendInt(0);

  //  Build the Subject part of the Certificate Request Info
  asnCertSubject := asnCertReqInfo.AppendSequenceR();

  //  Add each subject part..
  asnTemp := asnCertSubject.AppendSetR();
  success := asnTemp.AppendSequence2();
  //  AppendSequence2 updates the internal reference to the newly appended SEQUENCE.
  //  The OID and printable string are added to the SEQUENCE.
  success := asnTemp.AppendOid('2.5.4.6');
  success := asnTemp.AppendString('printable','US');
  asnTemp.Free;

  asnTemp := asnCertSubject.AppendSetR();
  success := asnTemp.AppendSequence2();
  success := asnTemp.AppendOid('2.5.4.8');
  success := asnTemp.AppendString('utf8','Utah');
  asnTemp.Free;

  asnTemp := asnCertSubject.AppendSetR();
  success := asnTemp.AppendSequence2();
  success := asnTemp.AppendOid('2.5.4.7');
  success := asnTemp.AppendString('utf8','Lindon');
  asnTemp.Free;

  asnTemp := asnCertSubject.AppendSetR();
  success := asnTemp.AppendSequence2();
  success := asnTemp.AppendOid('2.5.4.10');
  success := asnTemp.AppendString('utf8','DigiCert Inc.');
  asnTemp.Free;

  asnTemp := asnCertSubject.AppendSetR();
  success := asnTemp.AppendSequence2();
  success := asnTemp.AppendOid('2.5.4.11');
  success := asnTemp.AppendString('utf8','DigiCert');
  asnTemp.Free;

  asnTemp := asnCertSubject.AppendSetR();
  success := asnTemp.AppendSequence2();
  success := asnTemp.AppendOid('2.5.4.3');
  success := asnTemp.AppendString('utf8','example.digicert.com');
  asnTemp.Free;

  asnCertSubject.Free;

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

  asnPubKeyAlgId := asnPubKeyInfo.AppendSequenceR();
  success := asnPubKeyAlgId.AppendOid('1.2.840.113549.1.1.1');
  success := asnPubKeyAlgId.AppendNull();
  asnPubKeyAlgId.Free;

  //  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 := TAsn.Create;

  //  The RSA modulus is a big integer.
  success := asnRsaKey.AppendBigInt(keyModulus,'base64');
  success := asnRsaKey.AppendInt(65537);

  rsaKeyDerBase64 := asnRsaKey.GetEncodedDer('base64');

  //  Now add the RSA key DER as a BIT STRING.
  success := asnPubKeyInfo.AppendBits(rsaKeyDerBase64,'base64');
  asnPubKeyInfo.Free;

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

  //  Get the DER of the asnCertReqInfo.  
  //  This will be signed using the RSA private key.
  bdDer := TBinData.Create;
  success := asnCertReqInfo.WriteBd(bdDer);

  //  Add the signature to the ASN.1
  bdSig := TBinData.Create;
  success := rsa.SignBd(bdDer,'SHA1',bdSig);
  success := asnRoot.AppendBits(bdSig.GetEncoded('base64'),'base64');

  asnCertReqInfo.Free;

  //  ----------------------------------
  //  Finally, add the algorithm identifier, which is the 2nd sub-item under the root.
  //  ----------------------------------
  asnAlgId := asnRoot.GetSubItem(1);
  success := asnAlgId.AppendOid('1.2.840.113549.1.1.5');
  success := asnAlgId.AppendNull();
  asnAlgId.Free;

  //  Write the CSR to a DER encoded binary file:
  success := asnRoot.WriteBinaryDer('qa_output/mydomain.csr');
  if (success = False) then
    begin
      WriteLn(asnRoot.LastErrorText);
      Exit;
    end;

  //  It is also possible to get the CSR in base64 format:
  csrBase64 := asnRoot.GetEncodedDer('base64');

  WriteLn('Base64 CSR:');
  WriteLn(csrBase64);


  rsa.Free;
  privKey.Free;
  privKeyXml.Free;
  asnRoot.Free;
  asnRsaKey.Free;
  bdDer.Free;
  bdSig.Free;

end;

// ---------------------------------------------------------------------------

begin

  try
    RunDemo;
  except
    on E: Exception do
      WriteLn('Unhandled exception: ', E.ClassName, ': ', E.Message);
  end;

  WriteLn;
  {$IFDEF MSWINDOWS}
  WriteLn('Press Enter to exit...');
  ReadLn;
  {$ENDIF}
end.