meoooo
meoooo
Laboratory Session 5
RSA Public-Key Encryption (Part 1)
0.1 Overview
RSA (Rivest-Shamir-Adleman) is one of the first public-key cryptosystems and is widely used
for secure communication. The RSA algorithm first generates two large random prime num-
bers, and then uses them to generate public and private key pairs, which can be used to do
encryption, decryption, digital signature generation, and digital signature verification. The
RSA algorithm is built upon number theories, and it can be quite easily implemented with
the support of libraries. The learning objective of this lab is for students to gain hands-on
experiences on the RSA algorithm.
From lectures, students should have learned the theoretic part of the RSA algorithm, so they
know mathematically how to generate public/private keys and how to perform encryption/de-
cryption and signature generation/verification. This lab enhances students’ understanding of
RSA by requiring them to go through every essential step of the RSA algorithm on actual
numbers, so they can apply the theories learned from the class. Essentially, students will be
implementing the RSA algorithm using the C program language. The lab covers the following
security-related topics:
– Public-key cryptography
– The RSA algorithm and key generation
– Big number calculation
– Encryption and Decryption using RSA
– Digital signature
– X.509 certificate
0.2 Background
RSA algorithm involves computations on large numbers. These computations cannot be di-
rectly conducted using simple arithmetic operators in programs, because those operators can
only operate on primitive data types, such as 32-bit integer and 64-bit long integer types. The
numbers involved in the RSA algorithms typically more than 512 bits long. For example, to
multiply two 32-bit integer numbers a and b, we just need to use a*b in our program. However,
if they are big numbers, we cannot do that any more; instead, we need to use an algorithm
(i.e., a function) to compute their products.
There are several libraries that can perform arithmetic operations on integers of arbitrary size.
In this lab, we will use the Big Number library provided by openssl. To use this library, we
will define each big number as a BIGNUM type, and then use the APIs provided by the library
for various operations, such as addition, multiplication, exponentiation, modular operations,
etc.
1
0.2.1 BIGNUM APIs
All the big number APIs can be found from https://linux.die.net/man/3/bn. In the fol-
lowing, we describe some of the APIs that are needed for this lab.
– Some of the library functions requires temporary variables. Since dynamic memory al-
location to create BIGNUMs is quite expensive when used in conjunction with repeated
subroutine calls, a BN CTX structure is created to holds BIGNUM temporary variables used
by library functions. We need to create such a structure, and pass it to the functions that
requires it.
BN_sub(res, a, b);
BN_add(res, a, b);
– Compute res = a ∗ b. It should be noted that a BN CTX structure is need in this API.
BN_mul(res, a, b, ctx)
2
BN_mod_mul(res, a, b, n, ctx)
BN_mod_exp(res, a, c, n, ctx)
– Compute modular inverse, i.e., given a, find b, such that a ∗ b mod n = 1. The value b is
called the inverse of a, with respect to modular n.
BN_mod_inverse(b, a, n, ctx);
Listing 1: bn sample.c
#include <stdio.h>
#include <openssl/bn.h>
#define NBITS 256
int main ()
{
BN_CTX *ctx = BN_CTX_new();
BIGNUM *a = BN_new();
BIGNUM *b = BN_new();
BIGNUM *n = BN_new();
BIGNUM *res = BN_new();
// Initialize a, b, n
BN_generate_prime_ex(a, NBITS, 1, NULL, NULL, NULL);
BN_dec2bn(&b, "273489463796838501848592769467194369268");
BN_rand(n, NBITS, 0, 0);
// res = a*b
BN_mul(res, a, b, ctx);
printBN("a * b = ", res);
// res = a^b mod n
BN_mod_exp(res, a, b, n, ctx);
printBN("a^c mod n = ", res);
return 0;
}
3
Compilation. We can use the following command to compile bn sample.c (the character after
- is the letter l, not the number 1; it tells the compiler to use the crypto library).
p = F7E75FDC469067FFDC4E847C51F452DF
q = E85CED54AF57E53E092113E62F436F4F
e = 0D88C3
The public keys are listed in the followings (hexadecimal). We also provide the private key d
to help you verify your encryption result.
n = DCBFFE3E51F62E09CE7032E2677A78946A849DC4CDDE3A4D0CB81629242FB1A5
e = 010001 (this hex value equals to decimal 65537)
M = A top secret!
d = 74D806F9F3A62BAE331FFE3F0A68AFE35B3D2E4794148AACBC26AA381CD7D30D
C = 8C0F971DF2F3672B28811407E2DABBE1DA0FEBBBDFC7DCB67396567EA1E2493F
4
You can use the following python command to convert a hex string back to to a plain ASCII
string.
$ python -c 'print("4120746f702073656372657421".decode("hex"))'
A top secret!
0.4 Submission
Write your answers together with screenshots of your work in a single file by the name name id l5.pdf.
Submit that file to Blackboard.