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