Discuss this help topic in SecureBlackbox Forum

Encrypting data with asymmetric algorithm

With asymmetric, or public key, cryptography, you encrypt data with a recipient's public key. Upon receipt of the encrypted data the recipient decrypts it with his private key. This implies that everyone can encrypt data for a particular recipient. However, it's only the recipient who can decrypt this data. Often a public key of an entity is contained in its public X.509 certificates. The private key is typically contained in a separate file, or even on a hardware device.

Asymmetric algorithms operate with really small amounts of data (up to several hundreds of bytes), and asymmetric cryptography is rarely used to encrypt the data itself. Instead, the data is encrypted with a random symmetric 'session' key, and the session key itself is encrypted with the recipient's public key.

The two most common asymmetric encryption algorithms are RSA and Elgamal, with RSA being the absolute leader in popularity. Both are supported by SecureBlackbox. Encrypting a piece of data with an RSA key contained in a certificate can be performed in the following way:

  1. Create a TElRSAPublicKeyCrypto object (SBPublicKeyCrypto namespace; SecureBlackbox.dll assembly): TElRSAPublicKeyCrypto crypto = new TElRSAPublicKeyCrypto();
  2. Load the certificate into a TElX509Certificate object. Alternatively, you might wish to load a standalone key into TElRSAKeyMaterial. TElX509Certificate cert = new TElX509Certificate();
    int r = cert.LoadFromFileAuto("cert.cer", "");
    if (r != 0) throw new Exception("Failed to load certificate!");
    Note, that what you are loading here is a public certificate of the intended recipient of your piece of data. You don't need the private key at this point.
  3. Assign the certificate's key material object to the crypto's KeyMaterial property: crypto.KeyMaterial = cert.KeyMaterial; Note, that the cert.KeyMaterial property, being of an abstract TElPublicKeyMaterial type, should reference an instance of TElRSAKeyMaterial. This object will be automatically created and initialized if the certificate in the cert.cer file contains an RSA key.
  4. Set InputEncoding and OutputEncoding properties of the crypto object: crypto.InputEncoding = TSBPublicKeyCryptoEncoding.pkeBinary;
    crypto.OutputEncoding = TSBPublicKeyCryptoEncoding.pkeBinary;
  5. Encrypt the data with the Encrypt() method. Two options, buffer-based and stream-based, are available. The buffer-based option supports output length request calls common in Windows API:
    
    byte[] secretData = new byte[16] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
    
    // output length request
    byte[] encryptedSecretData = null;
    int encryptedSecretLen = 0;
    crypto.Encrypt(secretData, 0, secretData.Length, ref encryptedSecretData, 0, ref encryptedSecretLen);
    
    // adjusting the output buffer length:
    encryptedSecretData = new byte[encryptedSecretLen];
    
    // encrypting the data with a 'real' call:
    crypto.Encrypt(secretData, 0, secretData.Length, ref encryptedSecretData, 0, ref encryptedSecretLen);
    
    // as the estimated length might be larger than the real output, we might need to adjust buffer to the new encryptedSecretLen value:
    encryptedSecretData = SBUtils.Unit.CloneArray(encryptedSecretData, 0, encryptedSecretLen);
    			
    That's it. The encryptedSecretData array contains the encrypted data which can be sent to the recipient. Learn how to decrypt it here.

How To articles related to low-level cryptography

Discuss this help topic in SecureBlackbox Forum