Archived Forum Post

Index of archived forum posts

Question:

Delphi XE2 Public Key Encryption

May 13 '13 at 08:59

We're currently looking for a PKI encryption solution that can be accessed from the Delphi XE2 development environment. We need to be able to produce a public / private key pair and encrypt files using the the PKI cryptography method.

I've downloaded your Delphi DLL trial software and I'm looking at your code examples ("DSA Generate Key", "Encrypt File to PKCS7 .p7m"), The keys are generated successfully however I'm getting the error detailed below when attempting to use the public .PEM or .DER to encrypt a file.

Please can you provide any help?

ChilkatLog:
  CkEncryptFile:
    DllDate: Dec 13 2012
    UnlockPrefix: 30-day trial
    Username: ***
    Architecture: Little Endian; 32-bit
    Language: C++ Builder XE2
    VerboseLogging: 0
    hcCurDate: Mon, 13 May 2013 10:13:46 +0100
    hcExpire: 3/2013
    inputFile: [c:\temp\test.txt]
    outputFile: [c:\temp\test.txt.p7m]
    encryptionMethod: 1
    algorithm: pki
    buildRecipientInfo:
      issuerSerialNum: 
      Failed to get certificate's serial number
      Failed to create IssuerAndSerial ASN.1
    --buildRecipientInfo
    Failed to build RecipientInfo ASN.1
    Failed to build PKCS7 enveloped.
    Failed.
  --CkEncryptFile
--ChilkatLog

Here's the code that I'm using from your example…

CkCrypt2_putCryptAlgorithm(crypt,'PKI');

// Indicate the inner symmetric encryption algorithm to be used. // possible values are "aes", "des", "3des", and "rc2". // For this example, we'll use 256-bit AES encryption. CkCrypt2_putPkcs7CryptAlg(crypt,'aes'); CkCrypt2_putKeyLength(crypt,256);

// To encrypt, only a certificate w/ public key is needed. // (The certificate w/ private key is required for decryption.)

// The LoadFromFile method can load virtually any certificate format: // 1. DER encoded binary X.509 (.CER) // 2. Base-64 encoded X.509 (.CER) // 3. Cryptographic Message Syntax Standard - PKCS #7 Certificates (.P7B) // 4. PEM format encryptCert := CkCert_Create(); success := CkCert_LoadFromFile(encryptCert, 'dsa_pub.der'); if (success <> True) then begin Memo1.Lines.Add(CkCert__lastErrorText(encryptCert)); Exit; end;

// Tell the crypt object to use the certificate for encrypting: CkCrypt2_AddEncryptCert(crypt,encryptCert);

// Encrypt a file, producing a .p7m as output. // The input file is unchanged, the output .p7m contains the encrypted // contents of the input file. inFile := 'c:temptest.txt'; outFile := 'c:temptest.txt.p7m'; success := CkCrypt2_CkEncryptFile(crypt,inFile,outFile);


Answer

There is a conceptual misunderstanding between what is a digital certificate and what is a DSA/RSA key. A digital certificate is something that among other things, contains a DSA/RSA public key. A digital certificate contains information about the certificate owner (such as name, address, company name, etc.), it contains information about the issuing certificate, date of issue, etc., and it also contains the public-part of an RSA/DSA key. (The private components of the RSA/DSA are not stored within a certificate itself. They are typically stored in some sort of a protected keystore, or they can be contained in a secure PFX / .p12 file.)

In your code sample above, you created only the DSA key -- not an actual certificate. The solution is to instead create an RSA key (not DSA) and then use "Chilkat RSA" to encrypt using the bare RSA key. See this example: http://www.example-code.com/delphiDll/rsa_encryptStrings.asp

The "PKI" encryption/signature related methods in "Chilkat Crypt" (i.e. CkCrypt2) use digital certificates, whereas the "Chilkat RSA" methods work with bare RSA keys. Chilkat does not currently have (at the time of this writing, which is 13-May-2013) the ability to create a digital certificates. In any case, if it did, it would only be able to create self-signed certs. It takes a certificate authority to create certificates that are trusted by others outside your organization.