Reading a RSA key pair

In order to perform an RSA encryption or decryption in C you will need to have an RSA key. In the case of a RSA-2048 decryption, you will need a 2048 bits RSA key.

More information on generating a RSA key pair is described in our article on RSA key pair generation. For now we assume you have already generated on or already had one in your possession.

You can recognize a RSA key pair because it starts with a line with dashes around the string BEGIN RSA PRIVATE KEY or BEGIN PRIVATE KEY. In case of the latter you are not guaranteed it is a RSA key, because BEGIN PRIVATE KEY is also used for Elliptic Curve keys, for instance.

Let's get started

You will need to start by adding a random number generator to your application. We'll assume you use the CTR-DRBG generator and the context is called ctr_drbg. And that you RSA public key is called our-key.pub and the RSA private key is called our-key.pem.

In mbed TLS there is a direct way (by using the RSA module) and an advised way (by using the Public Key layer) to use RSA. This example will show the latter.

To use the Public Key layer you need to include the appropriate header file:

#include "mbedtls/pk.h"

RSA 2048-bit encryption

Ok, so how to do an RSA encryption in C?

Let's start by initializing the Public Key context and reading in the public key.

    int ret = 0;
    mbedtls_pk_context pk;

    mbedtls_pk_init( &pk );

    /*
     * Read the RSA public key
     */
    if( ( ret = mbedtls_pk_parse_public_keyfile( &pk, "our-key.pub" ) ) != 0 )
    {
        printf( " failed\n  ! mbedtls_pk_parse_public_keyfile returned -0x%04x\n", -ret );
        goto exit;
    }

We assume the data to be decrypted is stored in a variable to_decrypt and its length in to_decrypt_len.

For the actual encryption we assume the data you intend to encrypt is not too long! There is a maximum on how much data you can encrypt with RSA! For a 2048 bit RSA key this maximum is 245 bytes (or 1960 bits) that you can encrypt.

    unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
    size_t olen = 0;

    /*
     * Calculate the RSA encryption of the data.
     */
    printf( "\n  . Generating the encrypted value" );
    fflush( stdout );

    if( ( ret = mbedtls_pk_encrypt( &pk, to_encrypt, to_encrypt_len,
                                    buf, &olen, sizeof(buf),
                                    mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
    {
        printf( " failed\n  ! mbedtls_pk_encrypt returned -0x%04x\n", -ret );
        goto exit;
    }

So now our result is in buf with the actual size you should copy out in olen.

RSA 2048-bit decryption

And now on to an RSA decryption in C!

A decryption is very similar in set-up. The main difference is that we need the private key instead of the public key to perform the decryption. So let's start by initializing the PK context and reading in the 2048 bits private key.

    int ret = 0;
    mbedtls_pk_context pk;

    mbedtls_pk_init( &pk );

    /*
     * Read the RSA privatekey
     */
    if( ( ret = mbedtls_pk_parse_keyfile( &pk, "our-key.pem", "" ) ) != 0 )
    {
        printf( " failed\n  ! mbedtls_pk_parse_keyfile returned -0x%04x\n", -ret );
        goto exit;
    }

We assume the data to be decrypted is stored in a variable to_decrypt and its length in to_decrypt_len.

    unsigned char result[MBEDTLS_MPI_MAX_SIZE];
    size_t olen = 0;

    /*
     * Calculate the RSA encryption of the data.
     */
    printf( "\n  . Generating the encrypted value" );
    fflush( stdout );

    if( ( ret = mbedtls_pk_decrypt( &pk, to_decrypt, to_decrypt_len, result, &olen, sizeof(result),
                                    mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
    {
        printf( " failed\n  ! mbedtls_pk_decrypt returned -0x%04x\n", -ret );
        goto exit;
    }

So after the call to mbedtls_pk_decrypt() our result is in result with the actual size of the decrypted data in olen.

Did this help?