Прежде чем мы начнем, у меня есть сервер и клиент. Я хочу отправить клиенту зашифрованную строку, содержащую открытый статический ключ Диффи-Хеллмана сервера и открытый эфемерный ключ. Для этого я использую закрытый ключ RSA сервера для отправки зашифрованной строки, а клиент расшифровывает его с помощью открытого ключа RSA сервера.
Причина, по которой мне нужно сделать это таким образом, заключается в том, что сервер - единственный, у которого есть пара открытого / закрытого ключей. Это нормально, поскольку шифрование с использованием одной пары ключей по-прежнему отсекает одну сторону атаки MITM против Диффи-Хеллмана, и для моих требований это нормально.
Преобразование статических и эфемерных ключей в строку с шестнадцатеричным кодированием и отправка ее через сокет вызывает у меня проблему с этапом шифрования закрытого ключа.
мой сервер делает:
DH2 dhA(dh);
SecByteBlock sprivA(dhA.StaticPrivateKeyLength()), spubA(
dhA.StaticPublicKeyLength());
SecByteBlock eprivA(dhA.EphemeralPrivateKeyLength()), epubA(
dhA.EphemeralPublicKeyLength());
dhA.GenerateStaticKeyPair(rnd, sprivA, spubA);
dhA.GenerateEphemeralKeyPair(rnd, eprivA, epubA);
string sendBuf, recvBuf;
string saEncoded, eaEncoded, encoding;
cout << "spubA: " << (char*) spubA.data() << endl << "epubA: "
<< (char*) epubA.data() << endl;
SecByteBlock nil;
nil.CleanNew(HMAC< SHA256 >::DEFAULT_KEYLENGTH);
HMAC< SHA256 > hmac;
hmac.SetKey(nil.data(), nil.size());
HashFilter filter(hmac, new HexEncoder(new StringSink(encoding)));
filter.Put(spubA.data(), spubA.size());
filter.MessageEnd();
saEncoded = encoding;
encoding = "";
filter.Put(epubA.data(), epubA.size());
filter.MessageEnd();
eaEncoded = encoding;
encoding = "";
// StringSource saSource(spubA, sizeof(spubA), true,
// new HexEncoder(new StringSink(saEncoded)));
//
// StringSource eaSource(epubA, sizeof(epubA), true,
// new HexEncoder(new StringSink(eaEncoded)));
//
sendBuf = saEncoded + " " + eaEncoded;
cout << "Send Buffer: " << sendBuf << endl;
SendMsg(sendBuf, tdata);
где SendMsg()
содержит процесс шифрования.
На этом этапе он не работает:
void SendMsg( string sendBuf, struct ThreadData * tdata )
{
AutoSeededRandomPool rng;
Integer m, c, r;
stringstream ss;
try
{
// Encode the message as an Integer
m = Integer((const byte *) sendBuf.c_str(), sendBuf.size());
//Encrypt
c = tdata->privateKey.CalculateInverse(rng, m); //HERE!
С сообщением об ошибке:
InvertibleRSAFunction: computational error during private key operation
Код, который в настоящее время не закомментирован в разделе Диффи-Хеллмана, был получен из ЗДЕСЬ а>. Проблема с закомментированным кодом заключается в том, что когда клиент получает строку в шестнадцатеричной кодировке, он теряет данные и не может согласовать общий секрет. Но через розетку все же проходит.
Пример этого может быть показан:
Server:
spubA: &a�|՜D2�tu�cJ����B�R�8�*i�x?N���p��Q�����K��+O �"��P:k�d|3�����6Z
epubA: 4v������M�E�`l�K��[dN�|Q^r�-ż�����A~D�>4$�9���"v�*:Y��s�O���J��ow�M�߬�C�9n�;���Z�D�6lp�V��oowZ��WSv��",��A3��XL��8��
Send Buffer: 2661DC7CD59C4432AF747584634AF69BE60298429C52C738 3476CBCCFAA3B0A14DBE45E3606CC84B171DAC1CCE5B644E
Client:
Recovered: 2661DC7CD59C4432AF747584634AF69BE60298429C52C738 3476CBCCFAA3B0A14DBE45E3606CC84B171DAC1CCE5B644E
SA: 2661DC7CD59C4432AF747584634AF69BE60298429C52C738
EA: 3476CBCCFAA3B0A14DBE45E3606CC84B171DAC1CCE5B644E
Decoded SA: &a�|՜D2�tu�cJ����B�R�8
Decoded EA: 4v������M�E�`l�K��[dN
Что касается этого экземпляра, я попытался на стороне клиента сделать следующее:
// Get spubA and epubA from server
recovered = recoverMsg(serverKey, sockServer);
//Calculate shared secret.
string sa, ea;
ss.str(recovered);
ss >> sa >> ea;
ss.str("");
ss.clear();
cout << "SA: " << sa << endl << "EA: " << ea << endl;
string decodedSA, decodedEA;
StringSource decodeSA(sa, true,
new HexDecoder(new StringSink(decodedSA)));
StringSource decodeEA(ea, true,
new HexDecoder(new StringSink(decodedEA)));
cout << "Decoded SA: " << decodedSA << endl;
cout << "Decoded EA: " << decodedEA << endl;
SecByteBlock spubA((const byte*) decodedSA.data(), decodedSA.size());
if ( spubA.size() < dhB.StaticPublicKeyLength() ) spubA.CleanGrow(
dhB.StaticPublicKeyLength());
else spubA.resize(dhB.StaticPublicKeyLength());
SecByteBlock epubA((const byte*) decodedEA.data(), decodedEA.size());
if ( epubA.size() < dhB.EphemeralPublicKeyLength() ) epubA.CleanGrow(
dhB.EphemeralPublicKeyLength());
else epubA.resize(dhB.EphemeralPublicKeyLength());
Но я все равно получаю тот же результат.
Кто-нибудь знает, как я могу зашифровать это с помощью закрытого ключа сервера и правильно отправить его через сокет?
'A'
). После этого перейдите к буферу фиксированного размера со случайными данными (например, данными, содержащими'\0'
). Наконец, перейдите к настоящему файлу с настоящей подписью. Если у вас есть проблемы с фиксированным буфером, задайте вопрос об отправке / получении сокета. - person jww   schedule 04.12.2016