You are on page 1of 6

Quinton Martin

RSA Program:

#include "stdafx.h"

#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <stdio.h>
#include <string.h>

#define KEY_LENGTH 2048


#define PUB_EXP 3
#define PRINT_KEYS
#define WRITE_TO_FILE

int RSAA(void) {
size_t pri_len; // Length of private key
size_t pub_len; // Length of public key
char *pri_key; // Private key
char *pub_key; // Public key
char msg[KEY_LENGTH / 8]; // Message to encrypt
char *encrypt = NULL; // Encrypted message
char *decrypt = NULL; // Decrypted message
char *err; // Buffer for any error messages

// Generate key pair


printf("Generating RSA (%d bits) keypair...", KEY_LENGTH);
fflush(stdout);
RSA *keypair = RSA_generate_key(KEY_LENGTH, PUB_EXP, NULL, NULL);

// To get the C-string PEM form:


BIO *pri = BIO_new(BIO_s_mem());
BIO *pub = BIO_new(BIO_s_mem());

PEM_write_bio_RSAPrivateKey(pri, keypair, NULL, NULL, 0, NULL, NULL);


PEM_write_bio_RSAPublicKey(pub, keypair);

pri_len = BIO_pending(pri);
pub_len = BIO_pending(pub);

pri_key = malloc(pri_len + 1);


pub_key = malloc(pub_len + 1);

BIO_read(pri, pri_key, pri_len);


BIO_read(pub, pub_key, pub_len);

pri_key[pri_len] = '\0';
pub_key[pub_len] = '\0';

#ifdef PRINT_KEYS
printf("\n%s\n%s\n", pri_key, pub_key);
#endif
printf("done.\n");

// Get the message to encrypt


printf("Message to encrypt: ");
fgets(msg, KEY_LENGTH - 1, stdin);

Good stuff
Quinton Martin

msg[strlen(msg) - 1] = '\0';

// Encrypt the message


encrypt = malloc(RSA_size(keypair));
int encrypt_len;
err = malloc(130);
if ((encrypt_len = RSA_public_encrypt(strlen(msg) + 1, (unsigned char*)msg,
(unsigned char*)encrypt,
keypair, RSA_PKCS1_OAEP_PADDING)) == -1) {
ERR_load_crypto_strings();
ERR_error_string(ERR_get_error(), err);
fprintf(stderr, "Error encrypting message: %s\n", err);
goto free_stuff;
}

#ifdef WRITE_TO_FILE
// Write the encrypted message to a file
FILE *out = fopen("out.bin", "w");
fwrite(encrypt, sizeof(*encrypt), RSA_size(keypair), out);
fclose(out);
printf("Encrypted message written to file.\n");
free(encrypt);
encrypt = NULL;

// Read it back
printf("Reading back encrypted message and attempting decryption...\n");
encrypt = malloc(RSA_size(keypair));
out = fopen("out.bin", "r");
fread(encrypt, sizeof(*encrypt), RSA_size(keypair), out);
fclose(out);
#endif

// Decrypt it
decrypt = malloc(encrypt_len);
if (RSA_private_decrypt(encrypt_len, (unsigned char*)encrypt, (unsigned
char*)decrypt,
keypair, RSA_PKCS1_OAEP_PADDING) == -1) {
ERR_load_crypto_strings();
ERR_error_string(ERR_get_error(), err);
fprintf(stderr, "Error decrypting message: %s\n", err);
goto free_stuff;
}
printf("Encrypted message: %s\n", encrypt);
printf("Decrypted message: %s\n", decrypt);

free_stuff:
RSA_free(keypair);
BIO_free_all(pub);
BIO_free_all(pri);
free(pri_key);
free(pub_key);
free(encrypt);
free(decrypt);
free(err);
char* hold;
printf("Hold up:");
scanf("%s", hold);

Good stuff
Quinton Martin

return 0;
}

Result of run:

Signature Program:

#include "stdafx.h"

#include <stdio.h>
#include <string.h>
#include <openssl/opensslv.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/rand.h>

int Signat(int argc, char** argv)


{
RSA* pRsaKey = NULL;
unsigned char pDigest[32];
size_t uDigestLen = 32;
const char* szMessage = "qmartin115@rams.wssu.edu";
#if OPENSSL_VERSION_NUMBER >= 0x10100001L

Good stuff
Quinton Martin

EVP_MD_CTX *md_ctx;
#else
EVP_MD_CTX md_ctx;
#endif
unsigned char EM[128];
unsigned char pSignature[128];
unsigned char pDecrypted[128];
int status = 0;

/* openssl initialization */
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();

#ifdef _WIN32
RAND_screen();
#else
RAND_poll();
#endif

/* Generate an RSA key pair */


pRsaKey = RSA_generate_key(1024, 0x010001, NULL, NULL);
if (!pRsaKey)
{
printf("RSA_generate_key failed with error %s\n",
ERR_error_string(ERR_get_error(), NULL));
goto prog_end;
}

/* hash the message */


#if OPENSSL_VERSION_NUMBER >= 0x10100001L
md_ctx = EVP_MD_CTX_new();
EVP_DigestInit(md_ctx, EVP_sha256());
EVP_DigestUpdate(md_ctx, (const void*)szMessage, strlen(szMessage));
EVP_DigestFinal(md_ctx, pDigest, &uDigestLen);
EVP_MD_CTX_free(md_ctx);
#else
EVP_MD_CTX_init(&md_ctx);
EVP_DigestInit(&md_ctx, EVP_sha256());
EVP_DigestUpdate(&md_ctx, (const void*)szMessage, strlen(szMessage));
EVP_DigestFinal(&md_ctx, pDigest, (unsigned int *)&uDigestLen);
EVP_MD_CTX_cleanup(&md_ctx);
#endif

/* compute the PSS padded data */


status = RSA_padding_add_PKCS1_PSS(pRsaKey, EM, pDigest, EVP_sha256(), -2 /*
maximum salt length*/);
if (!status)
{
printf("RSA_padding_add_PKCS1_PSS failed with error %s\n",
ERR_error_string(ERR_get_error(), NULL));
goto prog_end;
}

/* perform digital signature */


status = RSA_private_encrypt(128, EM, pSignature, pRsaKey, RSA_NO_PADDING);
if (status == -1)
{

Good stuff
Quinton Martin

printf("RSA_private_encrypt failed with error %s\n",


ERR_error_string(ERR_get_error(), NULL));
goto prog_end;
}

/* now we will verify the signature


Start by a RAW decrypt of the signature
*/
status = RSA_public_decrypt(128, pSignature, pDecrypted, pRsaKey, RSA_NO_PADDING);
if (status == -1)
{
printf("RSA_public_decrypt failed with error %s\n",
ERR_error_string(ERR_get_error(), NULL));
goto prog_end;
}

/* verify the data */


status = RSA_verify_PKCS1_PSS(pRsaKey, pDigest, EVP_sha256(), pDecrypted, -2 /*
salt length recovered from signature*/);
if (status == 1)
{
printf("");
printf("Signature verification successfull!\n");
}
else
{
printf("RSA_verify_PKCS1_PSS failed with error %s\n",
ERR_error_string(ERR_get_error(), NULL));
goto prog_end;
}

prog_end:
if (pRsaKey)
RSA_free(pRsaKey);

/* openssl cleanup */
CRYPTO_cleanup_all_ex_data();
RAND_cleanup();
EVP_cleanup();
ERR_free_strings();
ERR_remove_state(0);

char* hold = "";


printf("Please hold.");
scanf("%s", hold);

return 0;
}

Result of run:

Good stuff
Quinton Martin

Good stuff

You might also like