C语言源代码RSA对任意长度的消息进行消息的分割和加密,并完成相应的解密
时间: 2024-01-21 07:16:18 浏览: 25
以下是C语言实现RSA对任意长度的消息进行消息的分割和加密,并完成相应的解密的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#define MAX_MSG_SIZE 10000 // 最大消息长度
#define MAX_BLOCK_SIZE 1000 // 最大块长度
#define PRIME_MAX 1000 // 素数范围
#define DEFAULT_PUBLIC_KEY 65537 // 默认公钥
// 求最大公因数
int gcd(int a, int b) {
if (b == 0) {
return a;
} else {
return gcd(b, a%b);
}
}
// 判断素数
int is_prime(int n) {
if (n <= 1) {
return 0;
}
for (int i = 2; i <= sqrt(n); i++) {
if (n % i == 0) {
return 0;
}
}
return 1;
}
// 生成随机素数
int generate_prime() {
int p = rand() % PRIME_MAX + 1;
while (!is_prime(p)) {
p = rand() % PRIME_MAX + 1;
}
return p;
}
// 扩展欧几里得算法
int exgcd(int a, int b, int *x, int *y) {
if (b == 0) {
*x = 1;
*y = 0;
return a;
} else {
int r = exgcd(b, a % b, x, y);
int t = *x;
*x = *y;
*y = t - a / b * (*y);
return r;
}
}
// 求模反元素
int mod_inverse(int a, int n) {
int x, y;
int r = exgcd(a, n, &x, &y);
if (r == 1) {
return (x + n) % n;
} else {
return -1;
}
}
// 加密
void encrypt(char *msg, int len, int n, int e) {
int block_num = len / MAX_BLOCK_SIZE + (len % MAX_BLOCK_SIZE == 0 ? 0 : 1);
int *encrypted_blocks = (int *)malloc(sizeof(int) * block_num);
for (int i = 0; i < block_num; i++) {
char *block = (char *)malloc(sizeof(char) * MAX_BLOCK_SIZE);
memset(block, 0, sizeof(char) * MAX_BLOCK_SIZE);
strncpy(block, &msg[i * MAX_BLOCK_SIZE], MAX_BLOCK_SIZE);
int m = 0;
for (int j = 0; j < strlen(block); j++) {
m += block[j] * pow(256, strlen(block) - j - 1);
}
int c = (int)pow(m, e) % n;
encrypted_blocks[i] = c;
free(block);
}
for (int i = 0; i < block_num; i++) {
printf("%d ", encrypted_blocks[i]);
}
printf("\n");
free(encrypted_blocks);
}
// 解密
void decrypt(int *encrypted_blocks, int block_num, int n, int d) {
char *decrypted_msg = (char *)malloc(sizeof(char) * MAX_MSG_SIZE);
memset(decrypted_msg, 0, sizeof(char) * MAX_MSG_SIZE);
for (int i = 0; i < block_num; i++) {
int m = (int)pow(encrypted_blocks[i], d) % n;
char *block = (char *)malloc(sizeof(char) * MAX_BLOCK_SIZE);
memset(block, 0, sizeof(char) * MAX_BLOCK_SIZE);
int index = 0;
while (m > 0) {
block[index++] = m % 256;
m /= 256;
}
for (int j = index - 1; j >= 0; j--) {
decrypted_msg[strlen(decrypted_msg)] = block[j];
}
free(block);
}
printf("%s\n", decrypted_msg);
free(decrypted_msg);
}
int main() {
srand(time(NULL));
int p = generate_prime();
int q = generate_prime();
int n = p * q;
int phi_n = (p - 1) * (q - 1);
int e = DEFAULT_PUBLIC_KEY;
while (gcd(phi_n, e) != 1) {
e++;
}
int d = mod_inverse(e, phi_n);
char msg[MAX_MSG_SIZE];
printf("请输入要加密的消息:");
fgets(msg, MAX_MSG_SIZE, stdin);
int len = strlen(msg) - 1;
encrypt(msg, len, n, e);
int block_num = len / MAX_BLOCK_SIZE + (len % MAX_BLOCK_SIZE == 0 ? 0 : 1);
int *encrypted_blocks = (int *)malloc(sizeof(int) * block_num);
for (int i = 0; i < block_num; i++) {
scanf("%d", &encrypted_blocks[i]);
}
decrypt(encrypted_blocks, block_num, n, d);
free(encrypted_blocks);
return 0;
}
```
该代码中采用了RSA算法进行加密和解密,具体过程如下:
1. 随机选择两个素数p和q,并计算n=p*q和φ(n)=(p-1)*(q-1)。
2. 随机选择一个整数e,满足gcd(φ(n), e)=1。
3. 计算d,使得d*e ≡ 1 (mod φ(n))。
4. 将消息分割成若干个块,每个块的长度不超过MAX_BLOCK_SIZE。
5. 对每个块进行加密,加密后的密文为c ≡ m^e (mod n),其中m为块的明文。
6. 将加密后的密文输出或传输给接收方。
7. 接收方对密文进行解密,解密后的明文为m ≡ c^d (mod n)。
8. 将解密后的明文块组合在一起即可得到原始消息。
该代码还实现了消息分块、模反元素求解以及整数转字节数组的操作。注意,该代码只适用于加密长度较短的消息,对于加密长消息需要采用分块加密的方式。