C语言源代码RSA对任意长度的消息进行消息的分割及加密,并完成相关的解密
时间: 2024-01-21 08:17:10 浏览: 151
RSA算法是非对称加密算法,它需要生成一对公私钥,其中公钥用于加密,私钥用于解密。下面是用C语言实现RSA加密和解密的代码,可以对任意长度的消息进行消息的分割及加密,并完成相关的解密。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#define MAX_MSG_LEN 1024
typedef struct {
int n;
int e;
} PublicKey;
typedef struct {
int n;
int d;
} PrivateKey;
int gcd(int a, int b) {
if (a == 0)
return b;
return gcd(b % a, a);
}
int power_mod(int base, int power, int mod) {
int result = 1;
while (power > 0) {
if (power & 1) {
result = (result * base) % mod;
}
base = (base * base) % mod;
power >>= 1;
}
return result;
}
int is_prime(int num) {
if (num <= 1)
return 0;
if (num <= 3)
return 1;
if (num % 2 == 0 || num % 3 == 0)
return 0;
for (int i = 5; i * i <= num; i += 6) {
if (num % i == 0 || num % (i + 2) == 0)
return 0;
}
return 1;
}
int find_prime(int min, int max) {
int num = rand() % (max - min + 1) + min;
while (!is_prime(num)) {
num = rand() % (max - min + 1) + min;
}
return num;
}
int get_public_key(int p, int q, PublicKey *pk) {
int n = p * q;
int euler = (p - 1) * (q - 1);
int e = rand() % (euler - 2) + 2;
while (gcd(e, euler) != 1) {
e = rand() % (euler - 2) + 2;
}
pk->n = n;
pk->e = e;
return euler;
}
int get_private_key(int p, int q, int e, PrivateKey *sk) {
int n = p * q;
int euler = (p - 1) * (q - 1);
int d = 1;
while ((d * e) % euler != 1 || d == e) {
d++;
}
sk->n = n;
sk->d = d;
return euler;
}
void split_msg(int *msg, int msg_len, int *splitted, int block_size) {
int block_count = ceil((double)msg_len / block_size);
for (int i = 0; i < block_count; i++) {
int block = 0;
for (int j = 0; j < block_size && i * block_size + j < msg_len; j++) {
block += msg[i * block_size + j] << (8 * (block_size - j - 1));
}
splitted[i] = block;
}
}
void encrypt(int *msg, int msg_len, PublicKey pk, int *encrypted, int block_size) {
int splitted[MAX_MSG_LEN / 4];
split_msg(msg, msg_len, splitted, block_size);
for (int i = 0; i < msg_len / block_size + (msg_len % block_size != 0); i++) {
int block = power_mod(splitted[i], pk.e, pk.n);
encrypted[i] = block;
}
}
void decrypt(int *encrypted, int block_count, PrivateKey sk, int *decrypted, int block_size) {
for (int i = 0; i < block_count; i++) {
int block = power_mod(encrypted[i], sk.d, sk.n);
for (int j = 0; j < block_size; j++) {
decrypted[i * block_size + j] = (block >> (8 * (block_size - j - 1))) & 0xff;
}
}
}
void print_hex(int *data, int len) {
for (int i = 0; i < len; i++) {
printf("%02x", data[i]);
}
printf("\n");
}
int main() {
srand(time(NULL));
int p = find_prime(100, 1000);
int q = find_prime(100, 1000);
PublicKey pk;
PrivateKey sk;
int euler = get_public_key(p, q, &pk);
get_private_key(p, q, pk.e, &sk);
printf("Public key: n=%d, e=%d\n", pk.n, pk.e);
printf("Private key: n=%d, d=%d\n", sk.n, sk.d);
int msg[MAX_MSG_LEN];
printf("Enter message to encrypt: ");
fgets((char *)msg, MAX_MSG_LEN, stdin);
int msg_len = strlen((char *)msg) - 1;
int block_size = ceil(log2(pk.n) / 8);
int splitted[MAX_MSG_LEN / 4];
encrypt(msg, msg_len, pk, splitted, block_size);
printf("Encrypted message: ");
print_hex(splitted, msg_len / block_size + (msg_len % block_size != 0));
int decrypted[MAX_MSG_LEN];
decrypt(splitted, msg_len / block_size + (msg_len % block_size != 0), sk, decrypted, block_size);
printf("Decrypted message: ");
for (int i = 0; i < msg_len; i++) {
printf("%c", decrypted[i]);
}
printf("\n");
return 0;
}
```
在这个代码中,我们首先使用 `find_prime()` 函数来获取两个素数 p 和 q,然后使用 `get_public_key()` 函数来生成公钥,使用 `get_private_key()` 函数来生成私钥。接下来,我们使用 `split_msg()` 函数将消息分割为多个块,并使用 `encrypt()` 函数对每个块进行加密。最后,使用 `decrypt()` 函数对加密后的块进行解密,并将其连接成原始消息。注意,在这个实现中,我们使用了固定的块大小,如果消息长度不是块大小的整数倍,则最后一个块将被填充到块大小,因此在解密时必须去除填充数据。
在实际中,RSA算法通常用于加密密钥等小数据,而不是对整个消息进行加密。因为RSA算法的加密速度较慢,对于大量数据的加密,通常使用对称加密算法。
阅读全文