Initial commit

This commit is contained in:
Lyanis SOUIDI 2024-04-06 14:13:39 +02:00
commit bbca46bf0b
Signed by: Lyanis SOUIDI
GPG Key ID: 202150AA0DAB9FAC
12 changed files with 3375 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/.vscode/
/.build/
/bin/

55
Makefile Normal file
View File

@ -0,0 +1,55 @@
LIB_DIR=lib
SRC_DIR=src
BUILD_DIR=.build
BIN_DIR=bin
CC=gcc
build: key_gen crypt_rsa crypt_rsa_file
key_gen: $(BIN_DIR)/key_gen
crypt_rsa: $(BIN_DIR)/crypt_rsa
crypt_rsa_file: $(BIN_DIR)/crypt_rsa_file
clean:
rm -r $(BUILD_DIR) $(BIN_DIR)
.PHONY: build key_gen crypt_rsa crypt_rsa_file clean
$(BIN_DIR)/key_gen: $(BUILD_DIR)/key_gen.o $(BUILD_DIR)/key_utils.o $(BUILD_DIR)/crypt_utils.o $(BUILD_DIR)/big.o
mkdir -p $(BIN_DIR)
$(CC) -o $@ $^
$(BIN_DIR)/crypt_rsa: $(BUILD_DIR)/crypt_rsa.o $(BUILD_DIR)/key_utils.o $(BUILD_DIR)/crypt_utils.o $(BUILD_DIR)/big.o
mkdir -p $(BIN_DIR)
$(CC) -o $@ $^
$(BIN_DIR)/crypt_rsa_file: $(BUILD_DIR)/crypt_rsa_file.o $(BUILD_DIR)/key_utils.o $(BUILD_DIR)/crypt_utils.o $(BUILD_DIR)/big.o
mkdir -p $(BIN_DIR)
$(CC) -o $@ $^
$(BUILD_DIR)/key_gen.o: $(SRC_DIR)/key_gen.c
mkdir -p $(BUILD_DIR)
$(CC) -c -o $@ $<
$(BUILD_DIR)/crypt_rsa.o: $(SRC_DIR)/crypt_rsa.c
mkdir -p $(BUILD_DIR)
$(CC) -c -o $@ $<
$(BUILD_DIR)/crypt_rsa_file.o: $(SRC_DIR)/crypt_rsa_file.c
mkdir -p $(BUILD_DIR)
$(CC) -c -o $@ $<
$(BUILD_DIR)/crypt_utils.o: $(SRC_DIR)/crypt_utils.c
mkdir -p $(BUILD_DIR)
$(CC) -c -o $@ $<
$(BUILD_DIR)/key_utils.o: $(SRC_DIR)/key_utils.c
mkdir -p $(BUILD_DIR)
$(CC) -c -o $@ $<
$(BUILD_DIR)/big.o: $(LIB_DIR)/big.c
mkdir -p $(BUILD_DIR)
$(CC) -c -o $@ $<

48
README.md Normal file
View File

@ -0,0 +1,48 @@
# Cryptographie RSA
Programme de cryptographie RSA utilisant la bibliothéque [bign](https://sourceforge.net/projects/bignlibacbignum/) afin de générer des clés, chiffrer et déchiffrer des entiers en hexadécimal et des fichiers.
## Build
```bash
make build
```
Les exécutables se trouvent dans le dossier `bin`.
## Utilisation
### Génération de clé
```bash
./key_gen rsa.key rsa.key.pub
```
### Chiffrement d'un entier
```bash
./crypt_rsa -e rsa.key.pub entier.txt entier.txt.rsa
```
### Déchiffrement d'un entier
```bash
./crypt_rsa -d rsa.key entier.txt.rsa entier.txt
```
### Chiffrement d'un ficher
```bash
./crypt_rsa -e rsa.key.pub fichier.txt fichier.txt.rsa
```
### Déchiffrement d'un ficher
```bash
./crypt_rsa -d rsa.key fichier.txt.rsa fichier.txt
```
## Auteurs
- Hugo Dimitijevic
- Lyanis Souidi

11
inc/crypt_utils.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef CRYPT_UTILS_H
#define CRYPT_UTILS_H
#include "../lib/big.h"
#include "key_utils.h"
void big_pow_mod(big_n a, big_n b, big_n n, big_n result);
void encrypt(public_key pub_key, big_n input, big_n output);
void decrypt(private_key priv_key, big_n input, big_n output);
#endif

20
inc/key_utils.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef KEY_UTILS_H
#define KEY_UTILS_H
#include "../lib/big.h"
typedef struct {
big_n n;
big_n e;
big_n d;
} private_key;
typedef struct {
big_n n;
big_n e;
} public_key;
private_key private_key_read(const char *file);
public_key public_key_read(const char *file);
#endif

2036
lib/big.c Normal file

File diff suppressed because it is too large Load Diff

669
lib/big.h Normal file

File diff suppressed because it is too large Load Diff

48
src/crypt_rsa.c Normal file
View File

@ -0,0 +1,48 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../lib/big.h"
#include "../inc/crypt_utils.h"
#include "../inc/key_utils.h"
int main(int argc, char *argv[]) {
public_key pub_key;
private_key priv_key;
big_n input_big, output_big;
FILE *input_file, *output_file;
if (argc != 5) {
fprintf(stderr, "Usage : %s <-e|-d> <clé> <fichier d'entrée> <fichier de sortie>\n", argv[0]);
return EXIT_FAILURE;
}
input_file = fopen(argv[3], "r");
if (!input_file) {
fprintf(stderr, "Une erreur est survenue lors de la lecture du fichier \"%s\".\n", argv[3]);
return EXIT_FAILURE;
}
read_hex(input_file, input_big);
fclose(input_file);
if (strcmp(argv[1], "-e") == 0) {
pub_key = public_key_read(argv[2]);
encrypt(pub_key, input_big, output_big);
} else if (strcmp(argv[1], "-d") == 0) {
priv_key = private_key_read(argv[2]);
decrypt(priv_key, input_big, output_big);
} else {
fprintf(stderr, "Commande \"%s\" invalide. Commandes disponibles :\n\t-e pour crypter\n\t-d pour décrypter\n", argv[2]);
return EXIT_FAILURE;
}
output_file = fopen(argv[4], "w");
if (!output_file) {
fprintf(stderr, "Une erreur est survenue lors de l'écriture du fichier \"%s\".\n", argv[4]);
return EXIT_FAILURE;
}
write_hex(output_file, output_big, '\n');
fclose(output_file);
return EXIT_SUCCESS;
}

106
src/crypt_rsa_file.c Normal file
View File

@ -0,0 +1,106 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "../lib/big.h"
#include "../inc/crypt_utils.h"
#include "../inc/key_utils.h"
void encrypt_file(public_key pub_key, const char *input_filepath, const char *output_filepath) {
FILE *input_file, *output_file;
size_t total_size, bits, encrypted_size, input_data_size;
big_n input_data, encrypted_data;
input_file = fopen(input_filepath, "r");
if (!input_file) {
fprintf(stderr, "Une erreur est survenue lors de la lecture du fichier \"%s\".\n", input_filepath);
exit(EXIT_FAILURE);
}
output_file = fopen(output_filepath, "w");
if (!output_file) {
fprintf(stderr, "Une erreur est survenue lors de l'ecriture du fichier \"%s\".\n", output_filepath);
exit(EXIT_FAILURE);
}
fseek(input_file, 0, SEEK_END);
total_size = ftell(input_file);
fseek(input_file, 0, SEEK_SET);
fwrite(&total_size, sizeof(total_size), 1, output_file);
bits = mssb(pub_key.n);
encrypted_size = (bits + 7) / 8;
input_data_size = (bits - 1) / 8;
zero_big(input_data);
while (fread(input_data, 1, input_data_size, input_file) > 0) {
encrypt(pub_key, input_data, encrypted_data);
fwrite(encrypted_data, 1, encrypted_size, output_file);
zero_big(input_data);
}
fclose(input_file);
fclose(output_file);
}
void decrypt_file(private_key priv_key, const char *input_filepath, const char *output_filepath) {
FILE *input_file, *output_file;
size_t total_size, bits, encrypted_size, output_data_size, total_written;
big_n encrypted_data, output_data;
input_file = fopen(input_filepath, "r");
if (!input_file) {
fprintf(stderr, "Une erreur est survenue lors de la lecture du fichier \"%s\".\n", input_filepath);
exit(EXIT_FAILURE);
}
output_file = fopen(output_filepath, "w");
if (!output_file) {
fprintf(stderr, "Une erreur est survenue lors de l'ecriture du fichier \"%s\".\n", output_filepath);
exit(EXIT_FAILURE);
}
fread(&total_size, sizeof(total_size), 1, input_file);
bits = mssb(priv_key.n);
encrypted_size = (bits + 7) / 8;
output_data_size = (bits - 1) / 8;
total_written = 0;
zero_big(encrypted_data);
while (fread(encrypted_data, 1, encrypted_size, input_file) > 0) {
decrypt(priv_key, encrypted_data, output_data);
fwrite(output_data, 1, (total_written + output_data_size > total_size) ? total_size - total_written : output_data_size, output_file);
total_written += output_data_size;
zero_big(encrypted_data);
}
fclose(input_file);
fclose(output_file);
}
int main(int argc, char *argv[]) {
private_key priv_key;
public_key pub_key;
if (argc != 5) {
fprintf(stderr, "Usage : %s <-e|-d> <clé> <fichier d'entrée> <fichier de sortie>\n", argv[0]);
return EXIT_FAILURE;
}
if (strcmp(argv[1], "-e") == 0) {
pub_key = public_key_read(argv[2]);
encrypt_file(pub_key, argv[3], argv[4]);
} else if (strcmp(argv[1], "-d") == 0) {
priv_key = private_key_read(argv[2]);
decrypt_file(priv_key, argv[3], argv[4]);
} else {
fprintf(stderr, "Commande \"%s\" invalide. Commandes disponibles :\n\t-e pour crypter\n\t-d pour décrypter\n", argv[2]);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

44
src/crypt_utils.c Normal file
View File

@ -0,0 +1,44 @@
#include <stdlib.h>
#include "../lib/big.h"
#include "../inc/key_utils.h"
#include "../inc/crypt_utils.h"
void big_pow_mod(big_n a, big_n b, big_n n, big_n result) {
big_n a_mod, b_mod, zero;
mod_big(n, a, a_mod);
mod_big(n, b, b_mod);
zero_big(zero);
zero_big(result);
result[0] = 1;
while (cp_abs(b_mod, zero) != 0) {
if (b_mod[0] % 2 == 1) {
mult_big(result, a_mod, result);
mod_big(n, result, result);
}
big_shift(-1, b_mod, b_mod);
mult_big(a_mod, a_mod, a_mod);
mod_big(n, a_mod, a_mod);
}
}
void encrypt(public_key pub_key, big_n input, big_n output) {
if (cp_abs(input, pub_key.n) < 0) {
fprintf(stderr, "Le nombre à crypter doit être inférieur au module de chiffrement.\n");
exit(EXIT_FAILURE);
}
big_pow_mod(input, pub_key.e, pub_key.n, output);
}
void decrypt(private_key priv_key, big_n input, big_n output) {
if (cp_abs(input, priv_key.n) < 0) {
fprintf(stderr, "Le nombre à décrypter doit être inférieur au module de chiffrement.\n");
exit(EXIT_FAILURE);
}
big_pow_mod(input, priv_key.d, priv_key.n, output);
}

257
src/key_gen.c Normal file
View File

@ -0,0 +1,257 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <time.h>
#include "../lib/big.h"
#include "../inc/key_utils.h"
#include "../inc/crypt_utils.h"
#define RM_ITERATIONS 100
#define RSA_KEY_SIZE 2048
void big_random_bits(size_t bits, big_n result) {
size_t i, size, index, offset;
uint8_t byte;
zero_big(result);
for (i = 0; i < bits; i++) {
byte = rand() % 256;
size = 8;
if (bits - i < 8) size = bits - i;
byte &= (1 << size) - 1;
index = i / 32;
offset = i % 32;
result[index] |= (uint32_t)byte << offset;
i += 8;
}
}
void big_random(big_n min, big_n max, big_n result) {
big_n range;
sub_big(min, max, range);
big_random_bits(mssb(range), result);
mod_big(range, result, result);
add_big(min, result, result);
}
void big_rmod(big_n a, big_n n, big_n result) {
big_n one, x, y, A, N, quotient, temp;
zero_big(one);
one[0] = 1;
if (cp_abs(n, one) == 0) {
zero_big(result);
return;
}
zero_big(x);
x[0] = 1;
zero_big(y);
copy_big(a, A);
copy_big(n, N);
while (cp_abs(A, one) < 0) {
div_big(N, A, quotient);
copy_big(N, temp);
mod_big(N, A, N);
copy_big(temp, A);
copy_big(y, temp);
mult_big(quotient, y, y);
sub_big(y, x, y);
copy_big(temp, x);
}
if (x[PREC] != 0) add_big(n, x, x);
copy_big(x, result);
}
void big_gcd(big_n a, big_n b, big_n result) {
big_n zero, a_mod, b_mod, mod;
zero_big(zero);
copy_big(a, a_mod);
copy_big(b, b_mod);
while (cp_abs(b_mod, zero) != 0) {
mod_big(b_mod, a_mod, mod);
copy_big(b_mod, a_mod);
copy_big(mod, b_mod);
}
copy_big(a_mod, result);
}
void private_key_write(private_key priv_key, const char *filepath) {
FILE *file = fopen(filepath, "w");
if (!file) {
fprintf(stderr, "Une erreur est survenue lors de l'ecriture du fichier \"%s\"*.\n", filepath);
exit(EXIT_FAILURE);
}
write_hex(file, priv_key.n, '\n');
write_hex(file, priv_key.e, '\n');
write_hex(file, priv_key.d, '\n');
fclose(file);
}
void public_key_write(public_key pub_key, const char *filepath) {
FILE *file = fopen(filepath, "w");
if (!file) {
fprintf(stderr, "Une erreur est survenue lors de l'ecriture du fichier \"%s\".\n", filepath);
exit(EXIT_FAILURE);
}
write_hex(file, pub_key.n, '\n');
write_hex(file, pub_key.e, '\n');
fclose(file);
}
bool is_prime(big_n n, int k) {
big_n zero, prime, mod, one, min, max, n1, d, a, x;
uint32_t firsts_primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101};
size_t i, r, j;
bool rm_prime_witness;
if (n[0] % 2 == 0)
return false;
if (n[0] < 2)
return false;
zero_big(zero);
zero_big(prime);
for (i = 0; i < sizeof(firsts_primes) / sizeof(uint32_t); i++) {
prime[0] = firsts_primes[i];
mod_big(prime, n, mod);
if (cp_abs(mod, zero) == 0)
return false;
}
zero_big(one);
one[0] = 1;
zero_big(min);
min[0] = 2;
copy_big(n, max);
sub_int(2, max, max);
copy_big(n, n1);
sub_int(1, n1, n1);
copy_big(n1, d);
r = 0;
while (d[0] % 2 == 0) {
r++;
big_shift(-1, d, d);
}
for (int i = 0; i < k; i++) {
big_random(min, max, a);
big_pow_mod(a, d, n, x);
if (cp_abs(x, one) == 0 || cp_abs(x, n1) == 0) continue;
rm_prime_witness = false;
for (j = 0; j < r; j++) {
mult_big(x, x, x);
mod_big(n, x, x);
if (cp_abs(x, one) == 0) return false;
if (cp_abs(x, n1) == 0) {
rm_prime_witness = true;
break;
}
}
if (!rm_prime_witness) return false;
}
return true;
}
void prime_gen(size_t bits, int k, big_n prime) {
big_random_bits(bits, prime);
prime[(bits - 1) / 32] |= 1 << ((bits - 1) % 32);
prime[0] |= 1;
while (!is_prime(prime, k)) add_int(2, prime, prime);
}
private_key private_key_gen() {
private_key priv_key;
big_n p, q, p1, q1, phi, one, cd;
prime_gen(RSA_KEY_SIZE / 2, RM_ITERATIONS, p);
prime_gen(RSA_KEY_SIZE / 2, RM_ITERATIONS, q);
mult_big(p, q, priv_key.n);
copy_big(p, p1);
sub_int(1, p1, p1);
copy_big(q, q1);
sub_int(1, q1, q1);
mult_big(p1, q1, phi);
zero_big(one);
one[0] = 1;
do {
big_random(one, phi, priv_key.e);
big_gcd(priv_key.e, phi, cd);
} while (cp_abs(cd, one) != 0);
big_rmod(priv_key.e, phi, priv_key.d);
return priv_key;
}
public_key public_key_gen(private_key priv_key) {
public_key pub_key;
copy_big(priv_key.n, pub_key.n);
copy_big(priv_key.e, pub_key.e);
return pub_key;
}
int main(int argc, char *argv[]) {
srand(time(NULL));
private_key priv_key;
public_key pub_key;
if (argc != 3) {
fprintf(stderr, "Usage : %s <clé privée> <clé publique>\n", argv[0]);
return EXIT_FAILURE;
}
priv_key = private_key_gen();
pub_key = public_key_gen(priv_key);
private_key_write(priv_key, argv[1]);
public_key_write(pub_key, argv[2]);
return EXIT_SUCCESS;
}

78
src/key_utils.c Normal file
View File

@ -0,0 +1,78 @@
#include "../lib/big.h"
#include "../inc/key_utils.h"
private_key private_key_read(const char *filepath) {
FILE *file;
private_key priv_key;
big_n zero;
file = fopen(filepath, "r");
if (!file) {
fprintf(stderr, "Une erreur est survenue lors de la lecture du fichier \"%s\".\n", filepath);
exit(EXIT_FAILURE);
}
read_hex(file, priv_key.n);
if (feof(file)) {
fprintf(stderr, "Clé privée \"%s\" invalide.\n", filepath);
exit(EXIT_FAILURE);
}
read_hex(file, priv_key.e);
if (feof(file)) {
fprintf(stderr, "Clé privée \"%s\" invalide.\n", filepath);
exit(EXIT_FAILURE);
}
read_hex(file, priv_key.d);
if (feof(file)) {
fprintf(stderr, "Clé privée \"%s\" invalide.\n", filepath);
exit(EXIT_FAILURE);
}
fclose(file);
zero_big(zero);
if (cp_abs(priv_key.n, zero) == 0 || cp_abs(priv_key.e, zero) == 0 || cp_abs(priv_key.d, zero) == 0) {
fprintf(stderr, "Clé privée \"%s\" invalide.\n", filepath);
exit(EXIT_FAILURE);
}
return priv_key;
}
public_key public_key_read(const char *filepath) {
FILE *file;
public_key pub_key;
big_n zero;
file = fopen(filepath, "r");
if (!file) {
fprintf(stderr, "Une erreur est survenue lors de la lecture du fichier \"%s\".\n", filepath);
exit(EXIT_FAILURE);
}
read_hex(file, pub_key.n);
if (feof(file)) {
fprintf(stderr, "Clé publique \"%s\" invalide.\n", filepath);
exit(EXIT_FAILURE);
}
read_hex(file, pub_key.e);
if (feof(file)) {
fprintf(stderr, "Clé publique \"%s\" invalide.\n", filepath);
exit(EXIT_FAILURE);
}
fclose(file);
zero_big(zero);
if (cp_abs(pub_key.n, zero) == 0 || cp_abs(pub_key.e, zero) == 0) {
fprintf(stderr, "Clé publique \"%s\" invalide.\n", filepath);
exit(EXIT_FAILURE);
}
return pub_key;
}