Spread the love

Tutorial By :- Abhishek Pandey (abhishek@firmcodes.com)

Hello friends, you must have listen somewhere about “asymmetric key cryptography”. So let me explain you what each word says.

Cryptography refers to techniques used for secure communication between two people in presence of some third person who might steal our secret data and may use it in a wrong way.

So basically cryptography deals with encryption and decryption of data which could only be possible with some keys which sender and receiver both have their own.

So here, a question arises, how much secure is this cryptography. It all depends on key size. Greater the size of keys, greater is the encryption and harder to guess the keys.

Now if we discuss about asymmetric keys, these are a pair of keys that are used to encrypt(lock) or decrypt(unlock) the data. That different keys are called as private key (which is kept private) and public key(that can be given to anyone to decrypt the data.)

There is one very important concept about the asymmetric key encryption is that, data once encrypted with a private key can only be decrypted with its public key and vice versa is also true.

But you must be thinking that if I decrypted the data with private key then anyone can access that using my public key. Yes it’s 100 % true but if you backtrack this, you’ll find that the data which I decrypted using that public key, the sender of that data can be the only one person, who encrypted that data using the private key.

By this property of asymmetric key encryption, if someone encrypted the data using private key, in future he cannot deny that he encrypted that specific data.

Now if we go through the reverse way, means if we encrypted the data using public key, it can only be decrypted using the private key.

At this point of time, I think you must be very confused which public key and private key I’m talking about. So clearing that thing, let me tell you that any user can generate it’s private key, and from that private key, a public key is also generated. And whatever the encryption and decryption is performed, is with help of those pair of keys. You cannot do like encrypt data using your private key and decrypt it using your friend’s public key.

Now let’s see how to generate private and public key pair.

For this you must have a Linux based PC with openssl package installed in it.

Go to terminal and create a directory named ‘rsa’ or whatever you want.

Then type in command :

openssl genrsa -out private.pem 4096

Above command will generate your private key in file name private.pem . Here 4096 refers to the no of bits of key you want to generate.

Output :-

-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAt+Yf0BH/aQmqXJd6LbTx
29uUHvThmbxFFOyF/bJRlk7CRvi1bOmzfUZxkbUrd3ohB3ndgoHyGGErDlJRu+Uw
51hZF9eARTInJZmt5wmB7z8BKacSnGj7f0Cj7KsTDQfIHhwkrCDPN4AlTS/jh1Ja
WpjTmzYrhFb8YWBOeAdAVpfwZKHBvxC2mjPdOamQOOvsGGDp0jZxn6RxQUojvd7x
+LxPtYTdVdz0tIriOLQlmBgyv9v9j8YeQZkAtGPfVrah5Y1xAJTeepqrrmt2jVTL
/tRTmShgAXNSny2jnYpp4MWM7Y+tUviEExmnzsXHFBtGsH1c0L9J09F3Dkc4mIKq
mn0oZeLUwnM5MS6EHRQ5OrogQ5uekZHYak+6pjZY9uzzoAD6+uY/Zb7Vxk5QRxQD
Wic8G7+KM4aDiXczfz3MQV23LfSBqY+PothXibA2ceB723wmEF5QwzYG50RKnw64
kcQ8Rtk6YEMAoTya/LHxcnHnNjSJf5DIq2MMhJpJ+k01B4O+PiJfgUscUhiaJfCN
Q4E6AQUnmmOdhFLWqWMOpEQ30MntSvPLk1aVyWBVUGK9e6quzx9CvG0eLSqtk4Tb
7V3cRd4XyzsLYcfOpUY2eJ/iVvtHEXOA3YiQUgX0/oujKL6K3Y+4BQjzDCB3+UpP
zlJYtwGJu7lqi+ttFdNW/YkCAwEAAQ==
-----END PUBLIC KEY-----

 

Again type in command :

openssl rsa -in private.pem -outform PEM -pubout -out public.pem

This command will generate your public key in file name public.pem

Output:-

-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

Now we will use the same key files for encrypting the text files or any given file using a C program:

Now create a file that contains data to encrypt.

For example,

echo "Welcome to Firmcode" > data
cat data
Welcome to Firmcode

Create a file , encrypt.c

#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <stdio.h>

int padding = RSA_PKCS1_PADDING;

/*Create RSA structue to pass inside 'RSA_private_encrypt' API method*/
RSA * createRSA(unsigned char * key,int isPublic)
{
    RSA *rsa= NULL;
    BIO *keybio ;
    keybio = BIO_new_mem_buf(key, -1);
    if (keybio==NULL)
    {
        printf( "Failed to create BIO of key");
        return 0;
    }
    if(isPublic)
    {
        rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa,NULL, NULL);
    }
    else
    {
        rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa,NULL, NULL);
    }
    if(rsa == NULL)
    {
        printf( "Failed to create RSA structure info");
    }

    return rsa;
}

/*Function to perform encryption on data*/
int private_encrypt(unsigned char * data,int data_len,unsigned char * key, unsigned char *encrypted)
{
    RSA * rsa = createRSA(key,0);
    int result = RSA_private_encrypt(data_len,data,encrypted,rsa,padding);
    return result;
}

/*Function to print previous error returned by the API method if any error caused*/
void printLastError(char *msg)
{
    char * err = malloc(130);;
    ERR_load_crypto_strings();
    ERR_error_string(ERR_get_error(), err);
    printf("%s ERROR: %s\n",msg, err);
    free(err);
}

/*main method*/
int main(int argc,char *argv[]){

 char buff;
 char plainText[2000];
 int size;
 FILE *fp;

char privateKey[4096];

unsigned char  encrypted[4096]={};
int encrypted_length;

/*Reading data from file which we want to encrypt*/
if(argc<2){
printf("Provide a file to encrypt\n");
exit(0);}
fp = fopen(argv[1],"r");
fseek(fp,0,SEEK_END);
size= ftell(fp);
fseek(fp,0,SEEK_SET);
fread(plainText,size,1,fp);
fclose(fp);

/*Reading private key from file*/

fp = fopen("private.pem","r");
if(fp==NULL)
{
	printf("First create private key\n");
	exit(0);
}
fseek(fp,0,SEEK_END);
size= ftell(fp);
fseek(fp,0,SEEK_SET);
fread(privateKey,size,1,fp);
fclose(fp);

/*Calling function to encrypt the plaintext and getting output inside buffer named 'encrypted'*/
encrypted_length = private_encrypt(plainText,strlen(plainText),privateKey,encrypted);

if(encrypted_length == -1)
{
    printLastError("Private Encrypt failed");
    exit(0);
}

/*Print encrypted text on console and write it in a file named 'encData'*/

fp = fopen("encData","w+");
printf("Encrypted Text =%s\n",encrypted);
fwrite(encrypted,sizeof(encrypted),1,fp);
fclose(fp);

/*Print encrypted length of data signature on console and write it in a file named 'encDataLen'
	It can also be calculed using API function 'RSA_size(rsa)' and pasing RSA structure as argument*/

fp = fopen("encDataLen","w+");
printf("Encrypted length =%d\n",encrypted_length);
fwrite(&encrypted_length,sizeof(encrypted_length),1,fp);
fclose(fp);

}

Compile using command –

gcc -o encrypt encrypt.c -lcrypto
./encrypt data

Output : –

Now create another file,let say decrypt.c

#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <stdio.h>

int padding = RSA_PKCS1_PADDING;

RSA * createRSA(unsigned char * key,int public)
{
    RSA *rsa= NULL;
    BIO *keybio ;
    keybio = BIO_new_mem_buf(key, -1);
    if (keybio==NULL)
    {
        printf( "Failed to create key BIO");
        return 0;
    }
    if(public)
    {
        rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa,NULL, NULL);
    }
    else
    {
        rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa,NULL, NULL);
    }
    if(rsa == NULL)
    {
        printf( "Failed to create RSA");
    }

    return rsa;
}

int public_decrypt(unsigned char * enc_data,int data_len,unsigned char * key, unsigned char *decrypted)
{
    RSA * rsa = createRSA(key,1);
    int  result = RSA_public_decrypt(data_len,enc_data,decrypted,rsa,padding);
    printf("\n RSA Length :%d \n",RSA_size(rsa));
    return result;
}

void printLastError(char *msg)
{
    char * err = malloc(130);;
    ERR_load_crypto_strings();
    ERR_error_string(ERR_get_error(), err);
    printf("%s ERROR: %s\n",msg, err);
    free(err);
}

int main(){

char publicKey[4096];

unsigned char decrypted[4098]={};
unsigned char encrypted[4098]={};
int decrypted_length;
int encrypted_length;
int size;
FILE *fp;

/*Reading data from file which we want to decrypt*/
 
 fp = fopen("encData","r");
 fseek(fp,0,SEEK_END);
 size= ftell(fp);
 fseek(fp,0,SEEK_SET);
 fread(encrypted,size,1,fp);
 fclose(fp);

/*Reading public key from file*/

 fp = fopen("public.pem","r");
 if(fp==NULL)
 {
   printf("First create a Public Key file\n");
   exit(0);
 }

 fseek(fp,0,SEEK_END);
 size= ftell(fp);
 fseek(fp,0,SEEK_SET);
 fread(publicKey,size,1,fp);
 fclose(fp);

/*Reading encrypted data length from file*/

 fp = fopen("encDataLen","r");
 fread(&encrypted_length,sizeof(encrypted_length),1,fp);
 fclose(fp);

/*Calling function to decrypt the encrypted text and getting output inside buffer named 'decrypted'*/

decrypted_length = public_decrypt(encrypted,encrypted_length,publicKey, decrypted);
if(decrypted_length == -1)
{
    printLastError("Public Decrypt failed");
    exit(0);
}

/*Writing decrypted data in file named 'origData'*/
fp = fopen("origData","w+");
printf("Decrypted Text =%s\n",decrypted);
printf("Decrypted Length =%d\n",decrypted_length);
fwrite(&decrypted,decrypted_length,1,fp);


}

Compile code using –

gcc -o decrypt decrypt.c

Run binary file –

./decrypt

Output –

RSA Length :512
Decrypted Text =Welcome to Firmcode
Decrypted Length =22

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~