我正在尝试为项目使用C语言实现RSA算法。
我可以生成所需的加密/解密密钥,但是似乎无法正确执行加密/解密。 错误似乎在于我如何计算加密邮件。它的数学公式是m ^ e mod n,其中m是消息,e是加密指数,n是公钥和私钥的模数。我使用pow()函数计算m ^ e,并同时使用fmod()函数和%n来计算mod n。似乎都不起作用(给出正确的输出)。
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
int p1,p2,mod,tot, encExp, decExp, conRelVal;
// Function to check if numbers given are primes
// @param pr: the number being tested
int prime(long int pr){
int i;
int j;
j = sqrt(pr);
for(i = 2; i <= j; i++){
if(pr % i == 0)
return 0;
}
return 1;
}
int gcd(int a, int h)
{
int temp;
while (1)
{
temp = a%h;
if (temp == 0)
return h;
a = h;
h = temp;
}
}
//function to generate encryption key
void encryption_key(){
p1 = 61;
p2 = 53;
conRelVal = 15;
mod = p1*p2;
tot = (p1-1)*(p2-1);
encExp = 12;
while (encExp < tot){
// e must be co-prime to the totient and
// smaller than the totient.
if (gcd(encExp,tot)==1)
break;
else
encExp++;
}
decExp = ((1+(conRelVal*tot))/encExp);
printf("p1=%d\np2=%d\nmod=%d\ntot=%d\ne=%d\nd=%d\nconst=%d\n",p1,p2,mod,tot, encExp, decExp, conRelVal);
printf("Public Key:\t(%d,%d)", mod,encExp);
printf("\nPrivate Key:\t(%d,%d)", mod,decExp);
}
double encrypt(int msg){
// Encryption c = (msg ^ e) % n
double l;
l = pow(msg, encExp);
int j;
j = ((int)l%mod);
l = fmod(l, mod);
printf("\nMessage:\t%d\nEncrypted:\t%lf",msg,l);
printf("\nMessage:\t%d\nEncrypted:\t%d",msg,j);
return l;
}
void decrypt(double cyp){
// Decryption m = (c ^ d) % n
double m ;
m = pow(cyp, decExp);
int z = ((int)m%mod);
m = fmod(m, mod);
printf("\nEncrypted:\t%lf\nDecrypted:\t%lf",cyp,m);
printf("\nEncrypted:\t%lf\nDecrypted:\t%d",cyp,z);
}
int main() {
encryption_key();
int msg = 123;
double cyp = encrypt(msg);
decrypt(cyp);
return 0;
}
Results:
$ ./test
p1=61
p2=53
mod=3233
tot=3120
e=17
d=2753
const=15
Public Key: (3233,17)
Private Key: (3233,2753)
Message: 123
Encrypted: 992.000000
Message: 123
Encrypted: -2194
Encrypted: 992.000000
Decrypted: nan
Encrypted: 992.000000
Decrypted: -2194
我希望加密为855 并解密为123
答案 0 :(得分:1)
如上所述,您不能在C数据类型中存储大量数字。解决方法是使用gmp。这是将与您的练习一起使用的代码。丢弃代码的第一部分,假设完成了模分解,它只是在破解私有指数。转到/ *加密功能* /我觉得这很丑...
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <gmp.h>
int main(void)
{
/* data */
int p = 61;
int q = 53;
size_t e = 17; /* public exponent */
size_t d; /* private exponent not given */
int msg = 123; /* message to be encrypted */
printf("==============\n");
printf("DATA\n");
printf("==============\n");
printf("int p = %d\n", p);
printf("int q = %d\n", q);
printf("int e = %ld\n", e);
printf("int msg = %d\n\n", msg);
/* compute modulo n */
int n = p*q;
printf("=========================\n");
printf("1 - Compute n = p * q\n");
printf("=========================\n");
printf("n = %d\n\n", n);
/* compute totient Euler function */
printf("==========================================================\n");
printf("2 - Compute totient Euler function phi(n) = (p-1)(q-1)\n");
printf("==========================================================\n");
int phi = (p-1) * (q-1);
printf("totient = %d\n\n", phi);
/* compute d private exponent */
printf("==========================================================\n");
printf("3 - Compute d private exponent d*e mod(phi(n)) = 1\n");
printf("==========================================================\n");
for (d = 1; d < ULONG_MAX; d++) {
int tmp = (d * e)%phi;
if (tmp == 1) {
printf("d is FOUND: %ld\n\n", d);
break;
}
}
/* encryption function */
printf("==========================================================\n");
printf("4 - ENCRYPTION of message 123 --> enc_msg = m^e mod(n)\n");
printf("==========================================================\n");
printf("modulo n = %d\n", n);
/* we are using gmp to be able to compute very large numbers */
mpz_t me; /* message^pub_exp */
mpz_t enc_msg; /* encrypted message */
mpz_t modn; /* modulo n previously computed "3233" */
mpz_inits(me, enc_msg, modn);
mpz_set_str(modn, "3233", 10); /* 10 means decimal number */
mpz_ui_pow_ui(me, msg, e); /* compute m^e */
mpz_mod(enc_msg, me, modn); /* compute m^e mod(n) */
printf("message^e mod(n) = ");
mpz_out_str(NULL, 10, enc_msg);
printf("\n\n");
/* decryption function */
printf("=============================================================\n");
printf("5 - DECRYPTION of enc_msg 855 --> dec_msg = enc_msg^d mod(n)\n");
printf("=============================================================\n");
printf("modulo n = %d\n", n);
int enc_message = 855; /* previously computed */
mpz_t md; /* enc_message^priv_exp */
mpz_t dec_msg; /* decrypted message */
mpz_inits(md, dec_msg, modn);
mpz_set_str(modn, "3233", 10);
mpz_ui_pow_ui(md, enc_message, d); /* compute enc_message^d */
mpz_mod(dec_msg, md, modn); /* compute enc_msg^d mod(n) */
printf("dec_msg^d mod(n) = ");
mpz_out_str(NULL, 10, dec_msg);
printf("\n\n");
/* free */
mpz_clear(me);
mpz_clear(md);
mpz_clear(modn);
mpz_clear(enc_msg);
mpz_clear(dec_msg);
return 0;
}
答案 1 :(得分:0)
通常,编程语言在变量中可以存储的数量方面受到限制。每当您尝试分配一个大于其可存储值的值时,它将环绕/四舍五入为最小值并再次开始计数。
我在这里很难解释。简而言之,我想说的是,您的计算可能出乎意料的错误,因为变量具有可以存储多少值的能力。因此,请确保没有溢出并且计算正确。如果计算结果错误,那么您的输出显然是错误的。