Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ RSA解密失败_C++_Rsa - Fatal编程技术网

C++ RSA解密失败

C++ RSA解密失败,c++,rsa,C++,Rsa,我正在尝试实现RSA加密方案,但尽管我的加密值似乎正确,但解密的值却不正确。根据我得到的p、q等值,计算部分(即硬部分)似乎很好,消息似乎加密正确(以防我也包括加密部分)。请注意,我应该在没有任何库的情况下完成这项工作(我已经使用GMP编写了它),所以这就是为什么我使用了不切实际的小数字 int main() { ... vector<uint64_t> encrypted = doEncrypt(e, n); doDecrypt(d, n, encrypte

我正在尝试实现RSA加密方案,但尽管我的加密值似乎正确,但解密的值却不正确。根据我得到的p、q等值,计算部分(即硬部分)似乎很好,消息似乎加密正确(以防我也包括加密部分)。请注意,我应该在没有任何库的情况下完成这项工作(我已经使用GMP编写了它),所以这就是为什么我使用了不切实际的小数字

int main()
{
    ...
    vector<uint64_t> encrypted = doEncrypt(e, n);
    doDecrypt(d, n, encrypted);
}
vector<uint64_t> doEncrypt(unsigned int e, unsigned int n)
{
    string message;
    vector<uint64_t> encrypted;
    cout << "Public key is <" << e << ", " << n << ">.\nPlease enter a message to encrypt: ";
    getline(cin, message);
    for (unsigned int i = 0; i < message.length(); i++)
        encrypted.push_back(encrypt(message[i], e, n));
    return encrypted;
}
uint64_t encrypt(char message, unsigned e, unsigned int n)
{
    int toencrypt = (int)message;
    cout << toencrypt << ' ';
    uint64_t result = pow64(toencrypt, e);
    return result%n;
}
void doDecrypt(unsigned int d, unsigned int n, vector<uint64_t> encrypted)
{
    cout << "Encrypted message is: ";
    for (unsigned int i = 0; i < encrypted.size(); i++)
    cout << encrypted[i] << ' ';
    cout << "\nDecrypted message is: ";
    char out;
    for (unsigned int i = 0; i < encrypted.size(); i++){
        decrypt(out, encrypted[i], d, n);
        cout << out << ' ';//This is only for diagnostics, I will
                       //take out the printing of the decrypted
                       //number and space later
    }
    cout << endl;
}

void decrypt(char& decrypted, uint64_t message, unsigned int d, unsigned int n)
{
    uint64_t decrypt = (pow64(message, d)%n);
    cout << decrypt;
    decrypted = (char)decrypt;
}

uint64_t pow64(uint64_t base, unsigned int ex)
{
    uint64_t back = 1;
    for (unsigned int i = 0; i < ex; i++)
        back = back * base;
    return back;
}
intmain()
{
...
向量加密=不加密(e,n);
十二加密(d,n,加密);
}
向量不加密(无符号整数e,无符号整数n)
{
字符串消息;
矢量加密;

你的问题是p==q,所以n是一个完美的平方,而不是两个素数的乘积,这意味着你对φ(n)的计算是错误的。φ(p^2)==p*(p-1),其中p是一个素数。所以如果你把代码改为使用φ(n)==506和d==225,它应该可以工作

或者选择不同的p和q

使用小素数测试代码时需要担心的另一个陷阱——如果明文值是p或q的倍数,则加密/解密将失败。使用实值(256位或更多)时,这极不可能发生对于p和q,但可能会在如此小的值下意外发生。命中此问题的概率与对手随机猜测您的私人因素的概率相同

第三个可能出现的陷阱是,您选择的公共指数
e
不得与φ(n)有任何共同因素,否则将不存在有效的
d
解码指数。同样,这与“真实”RSA密钥无关,如(p-1)/2和(q-1)/2应该是素数,因此只要
e
是奇数,没有有效解密密钥的可能性就非常小

编辑

您的代码存在一个问题,即pow64例程很容易溢出(515^269超过2000位)。请尝试使用:

uint64_t pow64(uint32_t base, uint32_t ex, uint32_t n)
{
    uint64_t back = 1;
    for (unsigned int i = 0; i < ex; i++)
        back = (back * base) % n;
    return back;
}
uint64\u t功率(uint32\u t基、uint32\u t ex、uint32\u t n)
{
uint64\u t back=1;
for(无符号整数i=0;i
请注意,我将输入值限制为uint32_t,因此中间乘法永远不会溢出64位。这也是非常低效的--最好是将基平方,然后一次遍历一位指数:

uint64_t pow64(uint32_t base, uint32_t ex, uint32_t n)
{
    uint64_t back = 1;
    for (uint64_t i = 1; i <= ex; i <<= 1) {
        if (i & ex)
            back = (back * base) % n;
        base = ((uint64_t)base * base) % n; }
    return back;
}
uint64\u t功率(uint32\u t基、uint32\u t ex、uint32\u t n)
{
uint64\u t back=1;

对于(uint64_t i=1;i加密消息包含空终止符?只是猜测…即使向量中有一个额外的值,我认为其余的值仍然可以工作。请澄清:您正在使用64位块的ECB?我想是的。包含加密字母的向量使用64位整数。p和q相同是一个微粒r run,在这次运行中,我随机选择了它们的值(或者更具体地说,选择一个随机的最小值并找到下一个素数),但后来我将它们的值设置为7和37(因此n是259,略大于最大的字符值255),同样的问题也会出现。RSA对m是p或q的倍数没有限制,解密将正常工作(假设p!=q与此处相同)。@Namfuak:使用7和37,您可能会遇到第二个或第三个陷阱…@Iridium:如果m是p或q的倍数,则(m^e)^d mod n可能是0,但不是m@Namfuak:如果您按照我的建议使用
d=225
,您的示例将正确解码为100 111 103