OpenSSL

Language: C

Security / Cryptography

OpenSSL was originally developed in 1998 and has become the de facto standard library for implementing secure communications in C/C++ applications. It is widely used in web servers, email servers, VPNs, and many security-sensitive software systems for encryption and certificate management.

OpenSSL is a robust, full-featured open-source toolkit implementing the Secure Sockets Layer (SSL) and Transport Layer Security (TLS) protocols. It provides cryptographic functions such as encryption, decryption, hashing, key generation, and certificate management.

Installation

linux: sudo apt install libssl-dev
mac: brew install openssl
windows: Download pre-built binaries from https://slproweb.com/products/Win32OpenSSL.html

Usage

OpenSSL provides APIs for symmetric and asymmetric encryption, digital signatures, hashing, SSL/TLS communication, and certificate handling. It supports a wide range of cryptographic algorithms including AES, RSA, ECC, SHA, and HMAC.

Generating an RSA key

#include <openssl/rsa.h>
#include <openssl/pem.h>

int main() {
    RSA *rsa = RSA_generate_key(2048, RSA_F4, NULL, NULL);
    FILE *fp = fopen("private.pem", "wb");
    PEM_write_RSAPrivateKey(fp, rsa, NULL, NULL, 0, NULL, NULL);
    fclose(fp);
    RSA_free(rsa);
    return 0;
}

Generates a 2048-bit RSA key and saves it as a PEM file.

Computing a SHA-256 hash

#include <openssl/sha.h>
#include <stdio.h>
#include <string.h>

int main() {
    unsigned char digest[SHA256_DIGEST_LENGTH];
    char str[] = "Hello, OpenSSL!";
    SHA256((unsigned char*)str, strlen(str), digest);
    for(int i = 0; i < SHA256_DIGEST_LENGTH; i++)
        printf("%02x", digest[i]);
    printf("\n");
    return 0;
}

Calculates and prints the SHA-256 hash of a string.

AES-256-CBC encryption

#include <openssl/evp.h>
#include <string.h>
#include <stdio.h>

int main() {
    unsigned char key[32] = "01234567890123456789012345678901";
    unsigned char iv[16] = "0123456789012345";
    unsigned char plaintext[] = "Hello, OpenSSL AES!";
    unsigned char ciphertext[128];
    int len, ciphertext_len;

    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);
    EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, strlen((char*)plaintext));
    ciphertext_len = len;
    EVP_EncryptFinal_ex(ctx, ciphertext + len, &len);
    ciphertext_len += len;
    EVP_CIPHER_CTX_free(ctx);

    printf("Encrypted text length: %d\n", ciphertext_len);
    return 0;
}

Encrypts a plaintext string using AES-256-CBC mode with a given key and IV.

Digital signature using RSA

#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/sha.h>

int main() {
    // Load private key
    FILE *fp = fopen("private.pem", "r");
    RSA *rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
    fclose(fp);

    unsigned char msg[] = "Hello";
    unsigned char sig[256];
    unsigned int sig_len;

    SHA256(msg, strlen((char*)msg), sig);
    RSA_sign(NID_sha256, sig, SHA256_DIGEST_LENGTH, sig, &sig_len, rsa);
    RSA_free(rsa);

    printf("Signature length: %u\n", sig_len);
    return 0;
}

Generates a digital signature of a message using RSA and SHA-256.

SSL/TLS client connection

#include <openssl/ssl.h>
#include <openssl/err.h>

int main() {
    SSL_library_init();
    SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
    SSL *ssl = SSL_new(ctx);
    // connect socket code omitted for brevity
    SSL_connect(ssl);
    SSL_shutdown(ssl);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    return 0;
}

Sets up a TLS client using OpenSSL. You can then connect to a server securely over SSL/TLS.

Error Handling

NULL pointer or allocation failure: Check function return values and handle memory allocation errors.
SSL handshake failure: Verify certificates, protocols, and cipher suites are compatible.
Digest or signature function fails: Ensure correct key size, padding, and hash algorithm usage.

Best Practices

Always check return values for errors to ensure cryptographic operations succeed.

Use updated and recommended algorithms (e.g., AES, SHA-256, RSA-2048+).

Securely store private keys and sensitive data in memory or protected files.

Use random number generators from OpenSSL for key generation.

Keep OpenSSL library updated to patch security vulnerabilities.