(CN) RSA Public-Key Encryption and Signature Lab
![](/post/seed_lab_3/featured_hu0eaaba4bfebe5127c9e3a92d3c000d7d_37089_629292ae6c940a802e8e45bdb28a7ece.webp)
RSA Public-Key Encryption and Signature Lab
Task 1 Deriving the Private Key
#include <stdio.h>
#include <openssl/bn.h>
#define NBITS 128
void printBN(char *msg, BIGNUM *a){
char *number_str = BN_bn2hex(a);
printf("%s %s\n", msg, number_str);
OPENSSL_free(number_str);
}
int main(){
//init
BN_CTX *ctx = BN_CTX_new();
BIGNUM *p = BN_new();
BIGNUM *q = BN_new();
BIGNUM *fai_n = BN_new();
BIGNUM *n = BN_new();
BIGNUM *e = BN_new();
BIGNUM *d = BN_new();
BIGNUM *res = BN_new();
BIGNUM *p_1 = BN_new();
BIGNUM *q_1 = BN_new();
//get value
BN_hex2bn(&p, "F7E75FDC469067FFDC4E847C51F452DF");
BN_hex2bn(&q, "E85CED54AF57E53E092113E62F436F4F");
BN_hex2bn(&e, "0D88C3");
//calculate
BN_sub(p_1, p, BN_value_one());
BN_sub(q_1, q, BN_value_one());
BN_mul(n, p, q, ctx);
BN_mul(fai_n, p_1, q_1, ctx);
// check if e and fai(n) is relatively prime
BN_gcd(res, fai_n, e, ctx);
if (!BN_is_one(res)){
printf("Error: e and fai(n) is not relatively prime \n ");
exit(0);
}
BN_mod_inverse(d, e, fai_n, ctx);
printBN("public key e=\t", e);
printBN("public key n=\t", n);
printBN("private key d=\t", d);
return 0;
}
![image-20230208105705992](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302081057061.png)
Task 2 Encrypting a Message
#include <stdio.h>
#include <openssl/bn.h>
#define NBITS 128
void printBN(char *msg, BIGNUM *a){
char *number_str = BN_bn2hex(a);
printf("%s %s\n", msg, number_str);
OPENSSL_free(number_str);
}
int main(){
//init
BN_CTX *ctx = BN_CTX_new();
BIGNUM *n = BN_new();
BIGNUM *e = BN_new();
BIGNUM *d = BN_new();
BIGNUM *msg = BN_new(); //massage
BIGNUM *p = BN_new(); //plaintxt
BIGNUM *c = BN_new(); //cyphertxt
//get value
BN_hex2bn(&n, "DCBFFE3E51F62E09CE7032E2677A78946A849DC4CDDE3A4D0CB81629242FB1A5");
BN_hex2bn(&e, "010001");
BN_hex2bn(&d, "74D806F9F3A62BAE331FFE3F0A68AFE35B3D2E4794148AACBC26AA381CD7D30D");
BN_hex2bn(&msg, "4120746f702073656372657421");
//calculate
BN_mod_exp(c, msg, e, n, ctx);
BN_mod_exp(p, c, d, n, ctx);
printBN("cyphertxt:", c);
printBN("plaintxt:", p);
return 0;
}
![image-20230208105643641](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302081056708.png)
Task 3 Decrypting a Message
#include<stdio.h>
#include<openssl/bn.h>
#define NBITS 128
void printBN(char *msg, BIGNUM *a){
char *number_str = BN_bn2hex(a);
printf("%s %s\n", msg, number_str);
OPENSSL_free(number_str);
}
int main(){
//init
BN_CTX *ctx = BN_CTX_new();
BIGNUM *n = BN_new();
BIGNUM *e = BN_new();
BIGNUM *d = BN_new();
BIGNUM *p = BN_new(); //plaintxt
BIGNUM *c = BN_new(); //cyphertxt
//get value
BN_hex2bn(&n, "DCBFFE3E51F62E09CE7032E2677A78946A849DC4CDDE3A4D0CB81629242FB1A5");
BN_hex2bn(&e, "010001");
BN_hex2bn(&d, "74D806F9F3A62BAE331FFE3F0A68AFE35B3D2E4794148AACBC26AA381CD7D30D");
BN_hex2bn(&c, "8C0F971DF2F3672B28811407E2DABBE1DA0FEBBBDFC7DCB67396567EA1E2493F");
//calculate
BN_mod_exp(p, c, d, n, ctx);
printBN("plaintxt:", p);
return 0;
}
![image-20230208105608714](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302081056804.png)
Task 4 Signing a Message
![image-20230208111641559](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302081116622.png)
#include <stdio.h>
#include <openssl/bn.h>
#define NBITS 128
void printBN(char *msg, BIGNUM *a){
char *number_str = BN_bn2hex(a);
printf("%s %s\n", msg, number_str);
OPENSSL_free(number_str);
}
int main(){
//init
BN_CTX *ctx = BN_CTX_new();
BIGNUM *n = BN_new();
BIGNUM *e = BN_new();
BIGNUM *d = BN_new();
BIGNUM *m1 = BN_new();
BIGNUM *m2 = BN_new();
BIGNUM *sig1 = BN_new();
BIGNUM *sig2 = BN_new();
//get value
BN_hex2bn(&n, "DCBFFE3E51F62E09CE7032E2677A78946A849DC4CDDE3A4D0CB81629242FB1A5");
BN_hex2bn(&e, "010001");
BN_hex2bn(&d, "74D806F9F3A62BAE331FFE3F0A68AFE35B3D2E4794148AACBC26AA381CD7D30D");
BN_hex2bn(&m1, "49206f776520796f75202432303030");
BN_hex2bn(&m2, "49206f776520796f75202433303030");
//calculate
BN_mod_exp(sig1, m1, d, n, ctx);
BN_mod_exp(sig2, m2, d, n, ctx);
printBN("signature of m1:", sig1);
printBN("signature of m2:", sig2);
return 0;
}
![image-20230208111947209](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302081119286.png)
可以发现,虽然信息只做了轻微的改动,签名结果却发生很大的变化。
Task 5 Verifying a Signature
![image-20230208113201340](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302081132396.png)
#include <stdio.h>
#include <openssl/bn.h>
#define NBITS 128
void printBN(char *msg, BIGNUM *a){
char *number_str = BN_bn2hex(a);
printf("%s %s\n", msg, number_str);
OPENSSL_free(number_str);
}
int main(){
//init
BN_CTX *ctx = BN_CTX_new();
BIGNUM *n = BN_new();
BIGNUM *e = BN_new();
BIGNUM *M = BN_new();
BIGNUM *m1 = BN_new();
BIGNUM *m2 = BN_new();
BIGNUM *sig1 = BN_new();
BIGNUM *sig2 = BN_new();
//get value
BN_hex2bn(&M, "4c61756e63682061206d697373696c652e");
BN_hex2bn(&n, "AE1CD4DC432798D933779FBD46C6E1247F0CF1233595113AA51B450F18116115");
BN_hex2bn(&e, "010001");
BN_hex2bn(&sig1, "643D6F34902D9C7EC90CB0B2BCA36C47FA37165C0005CAB026C0542CBDB6802F");
BN_hex2bn(&sig2, "643D6F34902D9C7EC90CB0B2BCA36C47FA37165C0005CAB026C0542CBDB6803F");
//calculate
BN_mod_exp(m1, sig1, e, n, ctx);
BN_mod_exp(m2, sig2, e, n, ctx);
//check if the result is valid
printf("verifying of signature1:");
if (BN_cmp(m1, M) == 0)
printf("valid!\n");
else
printf("invalid!\n");
printf("verifying of signature2:");
if (BN_cmp(m2, M) == 0)
printf("valid!\n");
else
printf("invalid!\n");
printBN("m1:", m1);
printBN("m2:", m2);
printBN("M:", M);
return 0;
}
![image-20230208115532253](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302081155328.png)
当签名没有损坏时,可以验证成功。即使签名只变动了一位,也会使得验证失败。