C语言实现RSA算法

该文章已生成可运行项目,

RSA 4K算法C语言实现

下面是一个完整的RSA 4096位(4K)算法的C语言实现,包含密钥生成、加密和解密功能。

完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <gmp.h>

// RSA密钥结构体
typedef struct {
    mpz_t n;     // 模数
    mpz_t e;     // 公钥指数
    mpz_t d;     // 私钥指数
    mpz_t p;     // 素数p
    mpz_t q;     // 素数q
    mpz_t phi;   // 欧拉函数φ(n)=(p-1)(q-1)
} RSAKey;

// 初始化RSA密钥
void rsa_init(RSAKey *key) {
    mpz_inits(key->n, key->e, key->d, key->p, key->q, key->phi, NULL);
}

// 清理RSA密钥
void rsa_clear(RSAKey *key) {
    mpz_clears(key->n, key->e, key->d, key->p, key->q, key->phi, NULL);
}

// 生成指定位数的随机素数
void generate_large_prime(mpz_t prime, unsigned int bits) {
    gmp_randstate_t state;
    gmp_randinit_default(state);
    gmp_randseed_ui(state, time(NULL) + clock());

    do {
        mpz_urandomb(prime, state, bits);
        mpz_nextprime(prime, prime);
    } while (mpz_sizeinbase(prime, 2) != bits);

    gmp_randclear(state);
}

// 生成RSA密钥对
void rsa_generate_keys(RSAKey *key, unsigned int key_size) {
    mpz_t temp, gcd;
    mpz_inits(temp, gcd, NULL);

    // 生成两个大素数p和q
    generate_large_prime(key->p, key_size / 2);
    do {
        generate_large_prime(key->q, key_size / 2);
    } while (mpz_cmp(key->p, key->q) == 0);

    // 计算n = p * q
    mpz_mul(key->n, key->p, key->q);

    // 计算φ(n) = (p-1)(q-1)
    mpz_sub_ui(temp, key->p, 1);
    mpz_sub_ui(key->phi, key->q, 1);
    mpz_mul(key->phi, key->phi, temp);

    // 设置公钥指数e (通常使用65537)
    mpz_set_ui(key->e, 65537);

    // 确保e和φ(n)互质
    mpz_gcd(gcd, key->e, key->phi);
    while (mpz_cmp_ui(gcd, 1) != 0) {
        mpz_add_ui(key->e, key->e, 2);
        mpz_gcd(gcd, key->e, key->phi);
    }

    // 计算私钥指数d = e^-1 mod φ(n)
    mpz_invert(key->d, key->e, key->phi);

    mpz_clears(temp, gcd, NULL);
}

// RSA加密
void rsa_encrypt(mpz_t cipher, mpz_t plain, RSAKey *pub_key) {
    mpz_powm(cipher, plain, pub_key->e, pub_key->n);
}

// RSA解密
void rsa_decrypt(mpz_t plain, mpz_t cipher, RSAKey *priv_key) {
    mpz_powm(plain, cipher, priv_key->d, priv_key->n);
}

// 将字符串转换为大整数
void string_to_mpz(mpz_t num, const char *str) {
    size_t len = strlen(str);
    mpz_import(num, len, 1, 1, 0, 0, str);
}

// 将大整数转换为字符串
char* mpz_to_string(mpz_t num) {
    char *str = mpz_get_str(NULL, 10, num);
    return str;
}

// 主函数演示
int main() {
    RSAKey key;
    rsa_init(&key);

    printf("正在生成4096位RSA密钥对...\n");
    rsa_generate_keys(&key, 4096);
    printf("密钥生成完成.\n");

    // 显示部分密钥信息
    printf("\n公钥 (n, e):\n");
    char *n_str = mpz_to_string(key.n);
    char *e_str = mpz_to_string(key.e);
    printf("n = %s\n\ne = %s\n", n_str, e_str);
    free(n_str);
    free(e_str);

    // 示例消息
    const char *message = "这是一条使用RSA 4K加密的测试消息!";
    mpz_t plaintext, ciphertext, decrypted;
    mpz_inits(plaintext, ciphertext, decrypted, NULL);

    printf("\n原始消息: %s\n", message);

    // 将消息转换为大整数
    string_to_mpz(plaintext, message);

    // 加密
    rsa_encrypt(ciphertext, plaintext, &key);
    printf("\n加密后的消息(数字形式):\n");
    char *cipher_str = mpz_to_string(ciphertext);
    printf("%s\n", cipher_str);
    free(cipher_str);
    
    // 解密
    rsa_decrypt(decrypted, ciphertext, &key);
    
    // 将解密结果转换回字符串
    size_t size = mpz_sizeinbase(decrypted, 256) + 2;
    char *decrypted_str = malloc(size);
    mpz_export(decrypted_str, NULL, 1, 1, 0, 0, decrypted);
    decrypted_str[size-1] = '\0';
    printf("\n解密后的消息: %s\n", decrypted_str);
    free(decrypted_str);
    
    // 清理
    mpz_clears(plaintext, ciphertext, decrypted, NULL);
    rsa_clear(&key);
    
    return 0;
}

编译和运行说明

安装依赖库

sudo apt-get install libgmp-dev # Ubuntu/Debian

sudo yum install gmp-devel # centos

编译程序

gcc rsa_4k_gmp.c -lgmp -o rsa_4k

运行程序

./rsa_4k

输出结果:

[rsa_4k_gmp]$ ./rsa_4k
正在生成4096位RSA密钥对...
密钥生成完成.

公钥 (n, e):
n = 807638600934126566667050274236454012613774208388540653758882747638608056985756701095965741414919828998854503173191042838521663897496765488010556633439115782570333449786433043998682776190264806808320846667793538519359556973018317982793685079209269064447300886594447902295032630158842698919942402177093088405921428926531523110305119020317808982755130678021432786555372485063793272031661896367541844402090163496716417051794659045068494525618109478782968062712345859275206447544175296611648030823023517519971950483689926660212025116776694099022172017212528338773023533093437570162792391029163557388718151562894574544156508941905682913823142024663401571953716588316236431657674522822028745252724173249579391597529695897730194078965997309763170972225283746891307019110920277757359649918010151324870083798783224223090918673669812017547528220149776809381139594597876127586968144325736019774045152443016727671014010329892587744143193190870016563084382226927895303368841656114901254256532805236312107546773268618936693781205876150804297179508475237639308856976064619612718467607597328333697323225105927733455481810395894479147643214628122530542386870328683979161585669118261408095656679489854512435891221287540523384395833480017645462886604693

e = 65537

原始消息: 这是一条使用RSA 4K加密的测试消息!

加密后的消息(数字形式):
617596063461692233127290789612198676717230579926912341843467244128098310470889778115762119048956216767287017531775919065003532418400987812638288924939488836054330093746724746375018455886739074971596694592075684049650634807509033045505657572853705550680868562026664256248833114435477110245366026342472327554320430582411192378327254856263401961583382378005351830980550924103167708758662292887107997861829713263749713461364205441876797891140518317191100096060533551527239190458369625161438339276346684883931349980520742707876653809609170481801810448525386091290487816271656124837408087508305694757696661024425743514709207542873193359557838377148181230174668953539766619642678499155620427156221704373825770637869975377728968938860506832884491143744209340634551541160640230530302025946416249772108398321676071245907573425447036751885086510403309683441273465907466514204859038937559935324051667592534739246838873088056710162873570849807085529467155674880831756665524255403126549549144575390581304111890174049089671223005328379278531698808104552039456481506762687401988994368477413415884016400915527999907847563931726013323583083784005384899651919184893058668150781832081555116331581991330674390526500194336624330220206388777233467353718865

解密后的消息: 这是一条使用RSA 4K加密的测试消息!

实现细节说明

  1. 大数运算:使用GMP库处理大整数运算,这是实现RSA所必需的。
  2. 密钥生成
    • 生成两个2048位的随机素数p和q
    • 计算模数n = p * q
    • 计算欧拉函数φ(n) = (p-1)(q-1)
    • 选择公钥指数e(通常为65537)
    • 计算私钥指数d = e⁻¹ mod φ(n)
  1. 加密过程:c = mᵉ mod n
  2. 解密过程:m = cᵈ mod n
  3. 消息处理:将字符串直接转换为大整数进行处理,实际应用中应使用适当的填充方案。

注意事项

  1. 性能考虑:4096位RSA操作较慢,特别是密钥生成过程可能需要几秒到几十秒时间。
  2. 安全性增强
    • 实际应用中应添加PKCS#1等填充方案
    • 使用更安全的随机数生成器
    • 考虑使用中国剩余定理(CRT)加速解密过程
  1. 内存管理:GMP库分配的内存需要手动释放,注意防止内存泄漏。

这个实现提供了RSA 4K算法的核心功能,可以作为学习RSA原理的基础,或进一步开发更完整加密系统的基础框架。

RSA 算法原理参考:

RSA算法原理(一)-优快云博客

RSA算法原理(二)-优快云博客

RSA的python实现方式参考:

python实现RSA算法-优快云博客

本文章已经生成可运行项目
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值