B4R Tutorial Using RSA on a ESP32 via Inline C

KMatle

Expert
Licensed User
Here's nother example how to use RSA on a ESP32 based on this documentation:

https://tls.mbed.org/kb/how-to/encrypt-and-decrypt-with-rsa

Notes:

- If the filesystem does not work, you need to format it with fs.format once.
- I've just copied the Public and Private Key from another app
- Both keys are written to file and then loaded with the mbed methods
- You can - of course - create keys by code (which is recommended). See the docs for it.
- See my and other examples how to use RSA
- The length of data to be en- and decrypted is limited by the algorythm (see the general RSA docs for it)


Create new keys:

I use a Windows *bat file to do this via Apache/OpenSSL (I have installed it via XAMPP). This is compatible with most platforms (B4x, PHP, .net, etc.)

B4X:
cd C:\xampp\apache\bin
openssl genrsa -out PrivateKey.pem 2048
openssl pkcs8 -topk8 -inform pem -in PrivateKey.pem -outform pem -nocrypt -out C:\Users\Klaus\Desktop\PrivateKey.pem
pause
B4R Code (no lib needed as mbed tls is included in the github repository you download to install everything for the ESP32)

B4X:
#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize: 50000
    #DefineExtra: #define SKIP_B4RNEW
#End Region

Sub Process_Globals
    Public Serial1 As Serial
    Private fs As ESP8266FileSystem
    
    Public bc As ByteConverter 'not needed
        
End Sub

Private Sub AppStart
    
    Serial1.Initialize(115200)
    
    Log("*** B4R AppStart ***")
    
    If Not(fs.Initialize()) Then
        Log("Unable to initialize File System")
        Return
    End If
    Log("File System successfully initialized")
    
'Write Public Key to file   
    fs.OpenReadWrite("/our-key.pub")
    Dim PubKey As String = JoinStrings(Array As String("-----BEGIN PUBLIC KEY-----", CRLF , "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmRdtXAQR/AN82QQmcGIt", CRLF , "JofGKgTEescayQshjA2Co+tVHRl10cUqUiTg9MxZe2S5rIlWU5qEB+pmDX3eXrAz", CRLF , "oGfvTf1V0qok1fRAPV8QAzJc7qAEUr+ryC3BokQ/0cD6ijmvPg8qv1fPl+jcviDn", CRLF , "sUVdkq34dYaQDDybpXamt2sPsi5O2w+/zXglzrzB2+SITABWn3FNnHElQkJOYpOM", CRLF , "Kf3vI6oRlLOjvsCaYqvmxSg4CTzWdc9trzS8dwVh/MXFuhdi6huwpM3p6ZHfWURm", CRLF , "9BThtx9MKB7N289/zrAkylOXeIGwgqJuP56gLwgJGlZmY9rZiXRoAsZheMpM13+b", CRLF , "bQIDAQAB", CRLF , "-----END PUBLIC KEY-----"))
    Log("Pub: ",bc.HexFromBytes(PubKey))
    Dim buffer() As Byte = bc.StringToBytes(PubKey)
    fs.Stream.WriteBytes(buffer, 0, buffer.Length)
    fs.Stream.Flush
    fs.Close
    
    Log("Pub Key written...")

'Write Private Key to file
    fs.OpenReadWrite("/our-key.pem")
    Dim PrivKey As String = JoinStrings(Array As String("-----BEGIN PRIVATE KEY-----", CRLF , "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCZF21cBBH8A3zZ", CRLF , "BCZwYi0mh8YqBMR6xxrJCyGMDYKj61UdGXXRxSpSJOD0zFl7ZLmsiVZTmoQH6mYN", CRLF , "fd5esDOgZ+9N/VXSqiTV9EA9XxADMlzuoARSv6vILcGiRD/RwPqKOa8+Dyq/V8+X", CRLF , "6Ny+IOexRV2Srfh1hpAMPJuldqa3aw+yLk7bD7/NeCXOvMHb5IhMAFafcU2ccSVC", CRLF , "Qk5ik4wp/e8jqhGUs6O+wJpiq+bFKDgJPNZ1z22vNLx3BWH8xcW6F2LqG7Ckzenp", CRLF , "kd9ZRGb0FOG3H0woHs3bz3/OsCTKU5d4gbCCom4/nqAvCAkaVmZj2tmJdGgCxmF4", CRLF , "ykzXf5ttAgMBAAECggEBAIqqv7HTNf8RoapoqfCt3LvDy+kPfHDBnC9yV6amLikP", CRLF , "5n5/K0sgzh6trN3Po1WzfMMdewYrNWB+HoYl9p/J9llbC1WXHH+/AbKSlQWB790V", CRLF , "Zzv10TSqzIx7daLnMu9pXwaJDYSm9E9w2GZ+1EObRoI5lHJiBmVdx2huFYWgnY4Q", CRLF , "kvRkEalL4IJ2IA1wl6J6zwOH3bWNDtsAz2Z6J5lHyto34/RpRwiLhlBweECR1pJS", CRLF , "AcYuTXFVrhOeFbvrZkJzXsz9KdpFUbwqj1XrcnSmsck2VCVyXUESruVzErqQltZe", CRLF , "uRDEP21oKkQFWg3boVycvwtWrEnFPJ/xs2k0o5wWeUECgYEAyDTwBDSNxL8S7x+A", CRLF , "iMtbUBbjXgs7aNGVkswnxWAg0KqdX1su/uL3nSlPGfX/Hoa95T8jHaDp2nZYSszV", CRLF , "IwBBMQF7GCcMh3BmI3/Xz4y7ZVb4r2xmb/nZTQ4o/wqZSMjbgbvz2AVVNDHbTsJ7", CRLF , "SXY5rfxH1f5cgBR5sC88J+nIG+UCgYEAw8E2gMIRFpppYJY8sVGpbXugtGIatLC1", CRLF , "P9G4h0l4LJs7nq1iWO/6oZffS6bpLbDgNcqOqXjUBFwg03+pfwT2ohah3mqjiaBW", CRLF , "goXvmrjfrXE5tJvSO2C4O8+d9qMt1s8v3HfrPtXzn2FH61DFFzxprKpgYLfBhAw3", CRLF , "7RtTJTox2OkCgYAsfbco+BTZOC0Y/sMtoyNztOJqL8zQCmNW8A+WiTpBpOi8HCNh", CRLF , "eUbVoix19Hjxa7gfjdxb5TqS1eHhHYvv70qNfWrBf0wFfTD1ip+G/BtY9e7l7Q0G", CRLF , "rVthCFiL9OsDhb9iIUabJvQ8WSgHZKjJNoCy7XF5WMFtpR81zAluRUG3EQKBgQC0", CRLF , "4HcICknX5N2xzaBPB/HRpAYeJvgeNZmEWrhy6UQNk3JHcFYLb9LaNYayVIvpGCJU", CRLF , "EdI4bdkaHjaGttNa9q8dnmP7K/XoWSsWd8Op52Fm1dRIOiLLktcpDPIczzKv5cmH", CRLF , "oZbQ/MibYDwgBwXWLpBGZzeepqw84z1Z7YGqSFd+4QKBgAveGZ6TZeqD6vdkckpR", CRLF , "cqkU7rwH6n+JXuttQOEcIo+BSVGk79MbJF/IvWpTqZNCz78F5c+UWaG4SXT8zyYA", CRLF , "+AXaWyIo2alxLiuRi9xihsVf27VMcs6/GXdJN75OZiRoE/W+QCwVfu3iKM/l1xpN", CRLF , "k6jYCK4WvnJR3QYImYpiW7CG", CRLF , "-----END PRIVATE KEY-----"))

    Dim buffer2() As Byte = bc.StringToBytes(PrivKey)
    fs.Stream.WriteBytes(buffer2, 0, buffer2.Length)
    fs.Stream.Flush
    fs.Close

    Log("Priv Key written...")

    'List files
    For Each f As File In fs.ListFiles("/")
        Log(f.Name)
    Next
    
    RunNative("RSA", Null)

End Sub



#if C
#include <mbedtls/aes.h>
#include "mbedtls/md.h"
#include "mbedtls/pk.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/entropy.h"

unsigned char encrypted[MBEDTLS_MPI_MAX_SIZE];
unsigned char decrypted[MBEDTLS_MPI_MAX_SIZE];

void RSA (B4R::Object* o) {

    memset(encrypted, 0, sizeof(encrypted));
    memset(decrypted, 0, sizeof(decrypted));
    
    int ret = 0;
    mbedtls_pk_context pk;

    mbedtls_pk_init( &pk );

    /*
     * Read the RSA public key
     */
    if( ( ret = mbedtls_pk_parse_public_keyfile( &pk, "/spiffs/our-key.pub" ) ) != 0 )
    {
        printf( " failed\n  ! mbedtls_pk_parse_public_keyfile returned -0x%04x\n", -ret );
         char errbuf[256];
        mbedtls_strerror( ret, errbuf, 200 );
        mbedtls_printf("Last error was: -0x%04x - %s\n\n", (int) -ret, errbuf );
    }
    printf("Pub Key loaded...\n");
    
    
    
    size_t olen = 0;
    unsigned char to_encrypt[] = "This is a test..";
    size_t to_encrypt_len = sizeof(to_encrypt);
    
    mbedtls_ctr_drbg_context ctr_drbg;
    char *personalization = "my_app_specific_string";
    
    mbedtls_entropy_context entropy;
    mbedtls_entropy_init( &entropy );
    mbedtls_ctr_drbg_init( &ctr_drbg );

    ret = mbedtls_ctr_drbg_seed( &ctr_drbg , mbedtls_entropy_func, &entropy,
                     (const unsigned char *) personalization,
                     strlen( personalization ) );

    if( ( ret = mbedtls_pk_encrypt( &pk, to_encrypt, to_encrypt_len,
                                    encrypted, &olen, sizeof(encrypted),
                                    mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
    {
        printf( " failed\n  ! mbedtls_pk_encrypt returned -0x%04x\n", -ret );
        char errbuf[256];
        mbedtls_strerror( ret, errbuf, 200 );
        mbedtls_printf("Last error was: -0x%04x - %s\n\n", (int) -ret, errbuf );
    }
    printf("Encrypted...\n");
    printf("encrypted: %i \n", sizeof(encrypted));
    printf("Olen: %i \n", olen);
    

int i;
for( i = 0; i < 256; i++ )
    {
        printf( "%02x[%c]%c", encrypted[i], (encrypted[i]>31)?encrypted[i]:' ', ((i&0xf)!=0xf)?' ':'\n' );
    }
    printf( "\n" );

//Decrypt

//int ret = 0;
    //mbedtls_pk_context pk1;
    mbedtls_pk_init( &pk );

    /*
     * Read the RSA privatekey
     */
    if( ( ret = mbedtls_pk_parse_keyfile( &pk, "/spiffs/our-key.pem", "" ) ) != 0 )
    {
        printf( " failed\n  ! mbedtls_pk_parse_keyfile returned -0x%04x\n", -ret );
      
    }
    printf("Priv Key loaded...\n");
    
    //olen = 0;
    //unsigned char decrypted[1024];
    /*
     * Calculate the RSA encryption of the data.
     */
    printf( "\n  . Decrypting...\n" );
    fflush( stdout );
    
    
    
    printf("encrypted: %i \n", sizeof(encrypted));
    printf("Olen: %i \n", olen);
    printf("Decrypted: %i \n", sizeof(decrypted));
    printf("1024: %i \n", 1024);
    
    if( ( ret = mbedtls_pk_decrypt( &pk, encrypted, olen, decrypted, &olen, sizeof(decrypted),
                                    mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
    {
        printf( " failed\n  ! mbedtls_pk_decrypt returned -0x%04x\n", -ret );
 
    }
    printf("Decrypted...\n");
    
    printf("Decrypted Text: %s \n", decrypted);
    


for( i = 0; i < 128; i++ )
    {
        printf( "%02x[%c]%c", decrypted[i], (decrypted[i]>31)?decrypted[i]:' ', ((i&0xf)!=0xf)?' ':'\n' );
    }
    printf( "\n" );
    
}

    



#End if
 
Top