2016-06-13 3 views
1

J'essaie d'utiliser le cryptage RSA de Crypto ++. Le problème est comment initialiser RSA::PrivateKey de chaîne de nombre?Comment initialiser RSA :: PrivateKey?

Le code pour générer des paires de clés (de here)

cout << hex ; 

AutoSeededRandomPool rng; 
InvertibleRSAFunction params; 
params.GenerateRandomWithKeySize(rng, 2048); 

params.SetPublicExponent(65537); 

const Integer& n = params.GetModulus(); 
const Integer& p = params.GetPrime1(); 
const Integer& q = params.GetPrime2(); 
const Integer& d = params.GetPrivateExponent(); 
const Integer& e = params.GetPublicExponent(); 

/////////////////////////////////////// 
// Dump 
cout << "RSA Parameters:" << endl; 
cout << " n: " << n << endl; 
cout << " p: " << p << endl; 
cout << " q: " << q << endl; 
cout << " d: " << d << endl; 
cout << " e: " << e << endl; 
cout << endl; 

Alors je me n, d, chaîne e, devrait être en mesure d'initialiser la clé privée, je trouve un exemple de code here:

Integer n("0xbeaadb3d839f3b5f"), e("0x11"), d("0x21a5ae37b9959db9"); 

RSA::PrivateKey privKey; 
privKey.Initialize(n, e, d); 

RSA::PublicKey pubKey; 
pubKey.Initialize(n, e); 

Le code fonctionne, il ne déclenche aucune exception. J'essaie donc de changer le n, e, d à la chaîne générée précédemment.

// n: b0f2bee69386528216049775704d402cb3ff443ca2ea25a74b11c1c9c321b7ea46327b4e413f532616812fece07d061cf96e373789b3b9b05d2d31174c700a066868d26c52b5d48e6dbaf664fac66ee31747133a6569e16d12f521b56a12aadd74e7cf2534353a5e338173b8f884a568a25173f3a33782f9047af59da9b21180534923e5210c3989851f0d69d68d92c272769fbf2a833e2f522f60f76bec12d3b194c2f3b945c913649e2be54295a2f58e7c040bf61421f01077fdf234ddfe73663deec8979256c721fd65c046a7d21530adec1af2922ed6a27004bf31a04cd57981ca22208572743b6b64d4d30b0efe446fc7608b4178ff8a0ba7db3e45ecf3h 
// e: 10001h 
// d: 246e365ca5e6f2de8c100110a62e05aed9c39d1b8af3f8b1806589c7a82c96ce59bf1962ef50cd5aaa47c61a2e37db9c8db4cf2205c31eb35e7a3ed017443e4c9d0685ace3da243b70f1c951067425e375bbcf40ba86bd7856b9ff691d5e323ca720aaa5c6fbe65eb0404c87f6ee220e034d0148bfb89af70873ab09df2c30c74104b0973aa4e93ca95db749da4f6b2d9594ab487db1f6f194ab0b77bd91d834daf269c63d3abecad54a1a71599524e679a425c55b16a9ff7f0c37b2d259eb44ea5782f314f61cc0ac874b2e6ae870d798e90e5bc96ab57c8fd904fa9d199c46c971de3a5d7cabfdca0663373843bd41ec246e158754dabc9ec2172f7a5982edh 

RSA::PrivateKey privKey; 
privKey.Initialize(n, e, d); 

Il se bloque. Je googlé un certain temps et trouvé some other tip:

InvertibleRSAFunction params; 
params.Initialize(n, e, d); 

RSA::PrivateKey(params); 

Mais il se bloque encore. Quelle est la bonne façon d'initialiser une clé privée RSA 2048 bits?

+0

Donc, 'RSA_PUB_KEY' est en fait le module? –

+0

Avez-vous changé les cordes d'une manière ou d'une autre? Selon la documentation, les entiers hexadécimaux devraient se terminer par 'h'. Voir 'std :: ostream & operator <<' http://www.cryptopp.com/docs/ref/class_integer.html#aa5f24aab6821fe59b7b161682b9a40cd –

+0

Je ne suis pas sûr qu'il est correct que private_key et public_key sont deux nombres impairs, et ils peuvent se remplacer. Et j'ai modifié la chaîne de sortie de cout <<. Il se termine par .h, je l'ai supprimé et ajouté "0x" avant, il semble correct pour CryptoPP :: Integer. – aj3423

Répondre

1
// n: b0f2bee69386528216049775704d402cb3ff443ca2ea25a74b11c1c9c321b7ea46327b4e413f532616812fece07d061cf96e373789b3b9b05d2d31174c700a066868d26c52b5d48e6dbaf664fac66ee31747133a6569e16d12f521b56a12aadd74e7cf2534353a5e338173b8f884a568a25173f3a33782f9047af59da9b21180534923e5210c3989851f0d69d68d92c272769fbf2a833e2f522f60f76bec12d3b194c2f3b945c913649e2be54295a2f58e7c040bf61421f01077fdf234ddfe73663deec8979256c721fd65c046a7d21530adec1af2922ed6a27004bf31a04cd57981ca22208572743b6b64d4d30b0efe446fc7608b4178ff8a0ba7db3e45ecf3h 
    // e: 10001h 
    // d: 246e365ca5e6f2de8c100110a62e05aed9c39d1b8af3f8b1806589c7a82c96ce59bf1962ef50cd5aaa47c61a2e37db9c8db4cf2205c31eb35e7a3ed017443e4c9d0685ace3da243b70f1c951067425e375bbcf40ba86bd7856b9ff691d5e323ca720aaa5c6fbe65eb0404c87f6ee220e034d0148bfb89af70873ab09df2c30c74104b0973aa4e93ca95db749da4f6b2d9594ab487db1f6f194ab0b77bd91d834daf269c63d3abecad54a1a71599524e679a425c55b16a9ff7f0c37b2d259eb44ea5782f314f61cc0ac874b2e6ae870d798e90e5bc96ab57c8fd904fa9d199c46c971de3a5d7cabfdca0663373843bd41ec246e158754dabc9ec2172f7a5982edh 
    RSA::PrivateKey privKey; 
    privKey.Initialize(n, e, d); 

Il tombe en panne.

Nous devons voir le code actuel. Je devine deux choses. First (1), vous n'utilisez pas try/catch, donc le programme se termine en raison de l'exception non interceptée. Pour résoudre ce problème:

try 
{ 
    // Some operation 
} 
catch (const Exception& ex) 
{ 
    cerr << ex.what() << endl; 
} 

deuxième (2), vous utilisez des chaînes plutôt que Entiers dans l'appel à Iniaitialize. Pour résoudre ce problème:

string n = "b0f2bee693865282...8a0ba7db3e45ecf3h"; 
string e = "10001h"; 
string d = "246e365ca5e6f2de...9ec2172f7a5982edh"; 

Integer _n(n.c_str()), _e(e.c_str()), _d(d.c_str()); 
RSA::PrivateKey privKey; 
privKey.Initialize(_n, _e, _d); 

Le deuxième problème doit avoir été intercepté par le compilateur. Vous devriez envisager d'utiliser -Wall pour obtenir un ensemble de base de diagnostics du compilateur.


Il existe un troisième problème potentiel. C'est la "clé ne parvient pas à valider" le cas. Si vous ajoutez un try/catch comme décrit dans (1), alors vous pouvez voir un "matériel de clé invalide" ou similaire de la classe CryptoMaterial. Dans ce cas, vos paramètres ne sont pas validés en fonction des contrôles effectués par Validate.

Validate est appelée par Initialize en utilisant un niveau de minutie faible (le paramètre level ci-dessous). La fonction Validate peut être trouvée dans le manuel au InvertibleRSAFunction::Validate. En suivant le lien Definition at line 247 of file rsa.cpp:

247 bool InvertibleRSAFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const 
    248 { 
    249  bool pass = RSAFunction::Validate(rng, level); 
    250  pass = pass && m_p > Integer::One() && m_p.IsOdd() && m_p < m_n; 
    251  pass = pass && m_q > Integer::One() && m_q.IsOdd() && m_q < m_n; 
    252  pass = pass && m_d > Integer::One() && m_d.IsOdd() && m_d < m_n; 
    253  pass = pass && m_dp > Integer::One() && m_dp.IsOdd() && m_dp < m_p; 
    254  pass = pass && m_dq > Integer::One() && m_dq.IsOdd() && m_dq < m_q; 
    255  pass = pass && m_u.IsPositive() && m_u < m_p; 
    256  if (level >= 1) 
    257  { 
    258   pass = pass && m_p * m_q == m_n; 
    259   pass = pass && m_e*m_d % LCM(m_p-1, m_q-1) == 1; 
    260   pass = pass && m_dp == m_d%(m_p-1) && m_dq == m_d%(m_q-1); 
    261   pass = pass && m_u * m_q % m_p == 1; 
    262  } 
    263  if (level >= 2) 
    264   pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); 
    265  return pass; 
    266 } 

La question ouverte reste peut-être, où a fait m_p, m_q, etc venir? La réponse est Initialize facteurs n basée sur e et d, et renseigne le CRT values comme p, q, dp, dq, etc. Il accélère le calcul plus tard.


Ceci peut être lié ....e=10001h me dit que Crypto ++ n'a probablement pas généré la paire de clés. Si Crypto ++ génère la paire de clés, il utilisera e=17 par défaut. Comment avez-vous généré la paire de clés?

+0

Il est causé par le e = 17. L'exposant est la valeur fixe 17 et ne peut pas être modifié lors de l'appel 'params.GenerateRandomWithKeySize (rng, 2048);'. Mon problème est que j'ai modifié l'exposant après que la clé ait été générée: 'params.SetPublicExponent (65537);', donc il imprime e == 0x10001 mais en fait la clé a été générée avec e == 0x11. – aj3423

+0

merci. C'est causé par l'exposant et semble résolu. J'utilise 'openssl genrsa --out key.pem 2048' et' openssl rsa -in key.pem -text' pour générer la paire de clés, par commodité. – aj3423

+0

*** '--out key.pem ...' *** - Crytpo ++ a un lecteur et un éditeur PEM sur le wiki Crypto ++ sur [PEM Pack] (http://www.cryptopp.com/wiki/Pem_pack) . Il fait partie de l'initiative [Category: Patch] (http://www.cryptopp.com/wiki/Category:Patch), où la bibliothèque fournit des éléments créés par des utilisateurs qui ne rentrent pas tout à fait dans la bibliothèque Crypto ++ proprement dite. C'est un peu comme un point de distribution central pour le contenu fourni par l'utilisateur afin que vous n'ayez pas à chercher sur le web pour d'éventuels déchets. – jww