2016-06-13 5 views
1

Я пытаюсь использовать шифрование RSA Crypto ++. Проблема в том, как инициализировать RSA::PrivateKey из числовой строки?Как инициализировать RSA :: PrivateKey?

Код для генерации пары ключей (от 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; 

Так я получаю н, д, е строку, должны иметь возможность инициализировать закрытый ключ, а затем я нашел некоторые примеры кода here:

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

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

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

Код работает, он не вызывает никаких исключений. Поэтому я пытаюсь изменить n, e, d на строку, созданную ранее.

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

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

Он падает. Я гугле некоторое время и нашел some other tip:

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

RSA::PrivateKey(params); 

Но она по-прежнему падает. Каков правильный способ инициализации закрытого ключа rsa 2048 бит?

+0

Значит, 'RSA_PUB_KEY' является модулем? –

+0

Вы каким-то образом изменили струны? Согласно документации, целые числа с шестнадцатеричным кодированием должны заканчиваться на 'h'. См. 'Std :: ostream & operator <<' http://www.cryptopp.com/docs/ref/class_integer.html#aa5f24aab6821fe59b7b161682b9a40cd –

+0

Я не уверен, что это правильно, что private_key и public_key - это два нечетных числа и они могут заменить друг друга. И я изменил строку, выводящую из cout <<. Он заканчивается на .h, я удалил его и добавил «0x» до него, кажется, что подходит для CryptoPP :: Integer. – aj3423

ответ

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

Он выходит из строя.

Нам нужно увидеть фактический код. Я угадываю две вещи. Сначала (1) вы не используете try/catch, поэтому программа завершается из-за неперехваченного исключения. Чтобы это исправить:

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

второй (2), вы используете строки, а не типа Integer в вызове Iniaitialize. Чтобы исправить это:

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); 

Вторая проблема должна быть уловлена ​​компилятором. Вы должны использовать -Wall, чтобы получить базовый набор диагностических данных компилятора.


Существует потенциальная третья проблема. Это «ключ не проверяет». Если вы добавите try/catch, как описано в (1), вы можете увидеть «Недопустимый материал ключа» или аналогичный из класса CryptoMaterial. В этом случае ваши параметры не проверяются в соответствии с проверками, выполненными Validate.

Validate вызывается Initialize с использованием низкоуровневой тщательности (параметр level). Функцию Validate можно найти в руководстве по адресу: InvertibleRSAFunction::Validate. Перейдя по ссылке 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 } 

Оставшийся открытым вопрос, может быть, где сделал m_p, m_q и т.д. взялось? Ответ Initialize факторы n на основе e и d и заполнит CRT values как p, q, dp, dq и т.д. Это ускоряет вычисление позже.


Это может быть связано ....e=10001h говорит мне, что Crypto ++, вероятно, не генерировал пару ключей. Если Crypto ++ сгенерировал пару ключей, то по умолчанию он будет использовать e=17. Как вы создали пару ключей?

+0

Это вызвано e = 17. Показатель является фиксированным значением 17 и не может быть изменен при вызове 'params.GenerateRandomWithKeySize (rng, 2048);'. Моя проблема в том, что я модифицировал экспонента после того, как ключ уже был сгенерирован: 'params.SetPublicExponent (65537);', поэтому он печатает e == 0x10001, но на самом деле ключ был сгенерирован с помощью e == 0x11. – aj3423

+0

спасибо. Это вызвано экспонентом и кажется решенным. Я использую 'openssl genrsa --out key.pem 2048' и' openssl rsa -in key.pem -text' для генерации пары ключей для удобства. – aj3423

+0

*** '--out key.pem ...' *** - Crytpo ++ имеет читатель и писатель PEM на вики Crypto ++ в [PEM Pack] (http://www.cryptopp.com/wiki/Pem_pack) , Его часть [Category: Patch] (http://www.cryptopp.com/wiki/Category:Patch), где библиотека поставляет материалы, созданные пользователями, которые не совсем вписываются в библиотеку Crypto ++. Его вид, как центральная точка распространения для контента, предоставленного пользователем, поэтому вам не нужно искать в Интернете для возможного мусора. – jww