Chilkat HOME .NET Core C# Android™ AutoIt C C# C++ Chilkat2-Python CkPython Classic ASP DataFlex Delphi ActiveX Delphi DLL Go Java Lianja Mono C# Node.js Objective-C PHP ActiveX PHP Extension Perl PowerBuilder PowerShell PureBasic Ruby SQL Server Swift 2 Swift 3,4,5... Tcl Unicode C Unicode C++ VB.NET VBScript Visual Basic 6.0 Visual FoxPro Xojo Plugin
(Unicode C) Duplicate openssl req -newkey rsa:2048 -nodes -keyout mydomain.pem -out mydomain.csrDemonstrates how to duplicate this OpenSSL command: openssl req -newkey rsa:2048 -nodes -keyout mydomain.pem -out mydomain.csr This command creates 2 files:
The second file is needed to pair with the certificate that will later be received from the CA.
#include <C_CkRsaW.h> #include <C_CkPrivateKeyW.h> #include <C_CkXmlW.h> #include <C_CkAsnW.h> #include <C_CkBinDataW.h> void ChilkatSample(void) { HCkRsaW rsa; BOOL success; 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; // 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. success = CkRsaW_GenerateKey(rsa,2048); if (success != TRUE) { wprintf(L"%s\n",CkRsaW_lastErrorText(rsa)); CkRsaW_Dispose(rsa); return; } privKey = CkRsaW_ExportPrivateKeyObj(rsa); // 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 != TRUE) { wprintf(L"%s\n",CkAsnW_lastErrorText(asnRoot)); CkRsaW_Dispose(rsa); 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); CkPrivateKeyW_Dispose(privKey); CkRsaW_Dispose(rsa); CkXmlW_Dispose(privKeyXml); CkAsnW_Dispose(asnRoot); CkAsnW_Dispose(asnRsaKey); CkBinDataW_Dispose(bdDer); CkBinDataW_Dispose(bdSig); } |
© 2000-2024 Chilkat Software, Inc. All Rights Reserved.