为什么在C中抛出“CryptoMaterial:此对象包含无效值”,但在python中工作正常

我正在与Mega.co.nz的API接口,使用
python库作为参考,这个代码正在抛出.私钥是临时帐户.

当我只使用第一个素数时它可以工作,但是如果我包含它抛出的第二个素数,但是在python代码中一切正常.

此代码抛出“CryptoMaterial:此对象包含无效值”

// g++ test.cpp -o test -lcryptopp
#include <iostream>

#include <cryptopp/rsa.h>
#include <cryptopp/integer.h>
#include <cryptopp/osrng.h>

using namespace CryptoPP;

const Integer c("10857166326382703760062779528766843368820930576598213227278471554906214169288262514203969639120532785228356073660117311791556795787311220009132632364495267243081665670086710276242234063736282452747089977833464270310556099739736793916154923086192702968111366046442015937417526298511445199340095898060147092158884693079554126699550560654798428433227449793922222881580173315635171540012289392792883134869370184160735204631001817822007869637755937740560912176149892518538187132538381475906064954503330035090788011376816518843886790979724470958150966813982521146398987188066116582925811581312709558507015381360737728282160");
const Integer n("13427557315502247597000078151163920443026153459996461135918747863095898679484680068841870307134991870634527490898047374333864169992533593470214214321618599580908993204307520436691605704402046321917552215500601059547120681142391461211832942043578807378527059669212765719156841060911214035328326209517003764423649629080809193207761562938380209994488934153009055462878017442054432223170713164757958714200660834201842865647297155663529615291314825578660639925675604438589594375258126020834604025620095899336598293228999530739615479725715448390873778015506002443516234879727296164834962067569248938506798206172807824155467");
const Integer d("11307416686738734818526381600980143530969392387365440956563156095238651519566046373761574995482098417376444202861513578386411932625291447132811969955047241752344415329943175104582404803706986376351622918316295629092312152540961230494175109089329522002970155510916013237184708261819969713960695755382740012146034212919647492076234405993178655740138052420647985859442037931597940897198569337697554456337486998070498389971468780232363941255237291940175758993311124407117751983734467699346428299766707608212611622303248258864115688090242455959830749262966169383160757942327094420226154106561552020347355716010319448907163");
const Integer p("100826948907457598414845964524448089304988432540271591225687687675999370502892903258891517574080931665624511494151970577170497712420499991942965423848183374943909439781466449525683097361603853112400332604761081878780250618758818492357490355994233490146112828080518628573284802902011591132699377690748913996743");
const Integer q("133174289820338768818359856956108213770008470949300663564909710605878037244519172983221279725814092327501516062026008560426937338300041407758960697270460830193354454791979178335037322285526761471721659139131141459697849499793713446217272909739442810866721995133352912243119263125394323211613915719804564581469");


int main(){
    AutoSeededRandomPool prng;

    InvertibleRSAFunction rsa;

    rsa.SetModulus(n);
    rsa.SetPrivateExponent(d);
    rsa.SetPrime1(p);
    rsa.SetPrime2(q); // Works fine if this line is removed
    RSA::PrivateKey privKey(rsa);

    Integer r = privKey.CalculateInverse(prng, c); // Throws here
    std::cout << "r: " << r << std::endl;
    return 0;
}

但是这个python代码有效:

from Crypto.PublicKey import RSA

c = 10857166326382703760062779528766843368820930576598213227278471554906214169288262514203969639120532785228356073660117311791556795787311220009132632364495267243081665670086710276242234063736282452747089977833464270310556099739736793916154923086192702968111366046442015937417526298511445199340095898060147092158884693079554126699550560654798428433227449793922222881580173315635171540012289392792883134869370184160735204631001817822007869637755937740560912176149892518538187132538381475906064954503330035090788011376816518843886790979724470958150966813982521146398987188066116582925811581312709558507015381360737728282160L
n = 13427557315502247597000078151163920443026153459996461135918747863095898679484680068841870307134991870634527490898047374333864169992533593470214214321618599580908993204307520436691605704402046321917552215500601059547120681142391461211832942043578807378527059669212765719156841060911214035328326209517003764423649629080809193207761562938380209994488934153009055462878017442054432223170713164757958714200660834201842865647297155663529615291314825578660639925675604438589594375258126020834604025620095899336598293228999530739615479725715448390873778015506002443516234879727296164834962067569248938506798206172807824155467L
d = 11307416686738734818526381600980143530969392387365440956563156095238651519566046373761574995482098417376444202861513578386411932625291447132811969955047241752344415329943175104582404803706986376351622918316295629092312152540961230494175109089329522002970155510916013237184708261819969713960695755382740012146034212919647492076234405993178655740138052420647985859442037931597940897198569337697554456337486998070498389971468780232363941255237291940175758993311124407117751983734467699346428299766707608212611622303248258864115688090242455959830749262966169383160757942327094420226154106561552020347355716010319448907163L
p = 100826948907457598414845964524448089304988432540271591225687687675999370502892903258891517574080931665624511494151970577170497712420499991942965423848183374943909439781466449525683097361603853112400332604761081878780250618758818492357490355994233490146112828080518628573284802902011591132699377690748913996743L
q = 133174289820338768818359856956108213770008470949300663564909710605878037244519172983221279725814092327501516062026008560426937338300041407758960697270460830193354454791979178335037322285526761471721659139131141459697849499793713446217272909739442810866721995133352912243119263125394323211613915719804564581469L

rsa_decrypter = RSA.construct( (n, 0L, d, p, q) )

print( rsa_decrypter.key._decrypt(c) )

最佳答案 我检查了来源.从RSAFunction :: Validate抛出异常,因为未设置e.

但是,设置e不会修复它,因为它也会从InvertibleRSAFunction :: Validate抛出,因为未设置dp,dq和u.

RSA私钥最低限度仅需要N,D.但是,通常还有五个整数P,Q,DP,DQ,QP.这些额外的整数是中间步骤,使计算更快.只使用N和D进行计算是可能但非常慢的.(基本上你必须做log2(D)次计算).

E是公共运营所必需的;但通常会将私钥发布为包含E的密钥对.

然而,Crypto私钥操作也使用E:它执行一些涉及随机数据的额外步骤,我认为这是为了防止定时攻击.

我猜测Python版本有效,因为它没有进行这种时间攻击预防;它还会计算任何缺失的值. (正如我所提到的,它们都可以从N和D计算,但这很慢).

这是为自己计算缺失值的附加代码,这对我有用:

rsa.SetModulus(n);
rsa.SetPrivateExponent(d);
rsa.SetPrime1(p);
rsa.SetPrime2(q);

// add this:
rsa.SetModPrime1PrivateExponent( d % (p-1) );
rsa.SetModPrime2PrivateExponent( d % (q-1) );
rsa.SetMultiplicativeInverseOfPrime2ModPrime1( q.InverseMod(p) );
rsa.SetPublicExponent( d.InverseMod((p-1) * (q-1)) );

请注意,一般情况下,私钥文件应该包含所有这些值 – 不管怎么说(对我而言)你会坐在那里N,D,P,Q而不是其他值.

点赞