尝试使用 C++ 上的 RSA 和 GMP 从文件中解密会产生不可预测的结果

Trying to decipher from a file using RSA on C++ with GMP yields unpredictable results

我正在尝试使用 GMP 库实现 RSA 算法。当我试图破译从文件中读取的加密值时,最终结果是一个比原始密文大几倍的值。 这是我的代码中有问题的部分:

void cipher_file(mpz_t E, mpz_t N, string Filename){

    // getting the file contents
    // and converting the letters to their ASCII values

    mpz_set_ui(CipheredLetter, TextASCII[j][k]);
    mpz_powm(CipheredLetter,CipheredLetter,E,N);
    // converting the resulting number to a string so that it can
    // be written on a file
    string AuxString(mpz_get_str(NULL,10,CipheredLetter));
    CipheredLine.push_back(AuxString);
}
void decipher_file(mpz_t D, mpz_t N, string Filename){

    // getting the file contents

    while(getline(CipheredFile,ReadLine)){
        stringstream Aux(ReadLine); 
        do{
            Aux >> AuxString;
            if(AuxString== "x") // end of line delimeter
                break; 
            
            mpz_set_str(DecipheredLetter,AuxString.c_str(),10);
            mpz_powm(DecipheredLetter,DecipheredLetter,D,N); 
        }while(Aux);
    }
}

加密函数逐个字母地工作,因此像 abc 这样的输入将作为 <ciphered a> <ciphered b> <ciphered b> 存储在加密文件中,即 a、[=16 的结果密码=] 和 c 以空格分隔。 EN 是 public 密钥的两个部分,其中 N 是模,E 是 (p-1)(q-1) 的互质,DN 是私钥的两部分。密钥生成按预期工作(生成素数 P 和 Q 我正在使用 Fermat 的素数测试,为了获得 D 我正在使用扩展欧几里得算法,GMP 的基本函数确认我的结果是正确的)。

问题发生在 decipher_file 函数中,在 mpz_powm 行。该行的结果应该是原始文件中字母的 ASCII 码,然而,结果不是某个巨大且看似随机的数字。

这是一个发生的例子(请注意,这些只是 64 位整数,但是这意味着能够更进一步,我只是用 64 位整数进行测试):

E = 1792236355377141527966304989230907
N = 4648032597737790824232209858880409
D = 2807452368750797442560595530474579

ASCII Code of Read Letter: 54
Ciphered Value: 835328461955738677042072153797186

Read from Ciphered File: 835328461955738677042072153797186
"Deciphered" Value: 211928638691469780709516904424482

我发现 this 使用 GMP 实现的简单(有点旧)RSA 实现与我的意图几乎相同,并且以与我几乎相同的方式实现,但是,他的作品好吧,出于我无法理解的原因。

感谢您阅读这么多。感谢任何帮助。

您的 N 没有两个不同的质因数:

4648032597737790824232209858880409 = 68176481265446597^2

这意味着您选择了p = q。除了明显的安全问题(n 可以通过取平方根轻松分解)之外,这还会在计算 N (reference) 的 Carmichael totient 函数时引起问题。具体来说,lambda(pq) = (p-1)*(q-1) 仅适用于 p != q。对于 p = q,您必须改用 lambda(p^2) = p(p-1)