【发布时间】:2019-01-21 14:40:14
【问题描述】:
我正在尝试在 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
我希望 Encrypted 为 855 并解密为123
【问题讨论】:
-
不要使用
pow(),你会严重失去精确度。 -
考虑快速功率算法或直接使用普通循环。您必须避免在此任务中完全、不惜一切代价使用浮点数。它是仅整数。
-
只有小“玩具”大小的 RSA 示例可以在标准 C 类型中实现。正确的加密使用至少数百位,最好是数千位,因此 64 位整数或浮点格式是不够的。此外,它们需要专门的算术例程,以便能够计算千位数字的大幂余数——必须计算千位余数而不实际计算完整的数百万位或更多幂.
-
mod 总是 > of d。这是不正确的