Switch Editions?
Cancel
Sharing:
Title:
URL:
Channel: CodeSection,代码区,网络安全 - CodeSec
Viewing all articles

# Pragmatically Generating a Self-Signed Certificate and Private Key usingOpenSSL

\$
0
0

Recently I found myself needing to generate a HTTPS Server Certificate and Private Key for an iOS app using OpenSSL, what surprised me was the total lack of documentation for OpenSSL.

While there is plenty of function documentation, what OpenSSL really lacks is examples of how it all fits together. It’s like having all of the pieces of a puzzle, but no picture of that the finished product will look like. Many online examples are insecure or make use of deprecated functions, a serious concern considering the consequences.

This tutorial will cover the basics for how to generate a RSA or ECDSA Private Key and a X509 Server Certificate for your application in C. For this tutorial, we will be using OpenSSL 1.0.1t.

Generating the PrivateKey

A private key is required for any PKI encryption setup, and you generally have two choices for algorithms: RSA and ECDSA.

ECDSA V.S.RSA

RSA has been the defacto standard for private keys for quite a long time, and if used correctly is still secure. The security of an RSA key relies on how large the “big number” is when the key is created. The recommended size of this number keeps going up and up as we’re getting better and better at breaking smaller numbers.

ECDSA keys, however, are created differently than RSA keys, and are much harder to break. In fact, no tangible progress has been made on solving the problem that ECDSA keys use ― The Elliptic Curve Discrete Logarithm Problem (ECDLP) ― since 1985. Because of this, ECDSA keys provide much greater security without the need for larger numbers. For example: a 256-bit ECDSA key is equivalent to a 3,248-bit RSA key.

Not only are ECDSA keys more secure than most RSA keys, they’re also much less CPU intensive. CloudFlare dissected the performance of the two in their write up on the algorithm .

sign/s 256 bit ecdsa (nistp256) 9516.8 rsa 2048 bits 1001.8 (openssl 1.0.2 beta on x86_64 with enable-ec_nistp_64_gcc_128)

To put it simply: ECDSA keys are 9x less CPU intensive while providing greater security than RSA keys.

Generating an RSA PrivateKey #include <openssl/x509.h> #include <openssl/rsa.h> ERR_load_CRYPTO_strings(); OPENSSL_add_all_algorithms_noconf(); EVP_PKEY * pkey = EVP_PKEY_new(); BIGNUM * bigNumber = BN_new(); int exponent = RSA_F4; if (BN_set_word(bigNumber, exponent) < 0) { // Error creating the big number // Use ERR_peek_last_error_line to find out why goto cleanup; } RSA * rsa = RSA_new(); if (RSA_generate_key_ex(rsa, 2048, // This is the length of your private key bigNumber, NULL) < 0) { // Error generating RSA key // Use ERR_peek_last_error_line to find out why goto cleanup; } EVP_PKEY_assign_RSA(pkey, rsa); cleanup: RSA_free(rsa); BN_free(bigNumber); Generating a ECDSA PrivateKey #include <openssl/x509.h> #include <openssl/ecdsa.h> ERR_load_CRYPTO_strings(); OPENSSL_add_all_algorithms_noconf(); EVP_PKEY * pkey = EVP_PKEY_new(); EC_KEY * ecc = EC_KEY_new_by_curve_name(NID_secp256k1); if (!ecc) { // Error selecting curve // Use ERR_peek_last_error_line to find out why } EC_KEY_set_asn1_flag(ecc, OPENSSL_EC_NAMED_CURVE); if (EC_KEY_generate_key(ecc) < 0) { // Error generating key // Use ERR_peek_last_error_line to find out why } if (EVP_PKEY_assign_EC_KEY(pkey, ecc) < 0) { // Error assigning key to pkey class // Use ERR_peek_last_error_line to find out why } Generating the Server Certificate

The server certificate is the client-facing piece of information that details the connection to the server. It tells the client what type of cipher to use, and validates the identity of the server. We’re generating a self-signed certificate in this case, so your computer won’t trust the certificate until you install it locally.

OpenSSL encourages that you use their built-in methods for writing to the disk as they can automatically encrypt the private key contents using a password and cipher of your choice.

It’s absolutely vital ― and I cannot stress this enough ― that you keep your private key safe.

At a minimum, you should be changing the file permissions to not be world-readable. Jeff Atwood has a good write-up on Keeping Private Keys Private .

#include <openssl/x509.h> #include <openssl/pem.h> ERR_load_CRYPTO_strings(); OPENSSL_add_all_algorithms_noconf(); const char * encryptionPassword = "MySuperDuperSecurePassword"; FILE * f = fopen("./private_key.pem", "wb"); // Here you write the private key (pkey) to disk. OpenSSL will encrypt the // file using the password and cipher you provide. if (PEM_write_PrivateKey(f, pkey, EVP_des_ede3_cbc(), (unsigned char *)encryptionPassword, (int)strlen(encryptionPassword), NULL, NULL) < 0) { // Error encrypting or writing to disk. // Use ERR_peek_last_error_line to find out why fclose(f); } fclose(f); f = fopen("./server_cert.pem", "wb"); // Here you write the certificate to the disk. No encryption is needed here // since this is public facing information if (PEM_write_X509(f, x509) < 0) { // Error writing to disk. // Use ERR_peek_last_error_line to find out why fclose(f); } fclose(f); Verifying our Server Certificate

OpenSSL has a nifty little function that lets you quickly print out the summary of a X509 certificate to a file (or stdout):

X509 * cert = ... X509_print_fp (stdout, cert);

Inspecting the certificate created with a RSA private key:

Viewing all articles

### 汤唯被删大尺度全裸激情床戏曝光（图）

More Pages to Explore .....