Вчера я установил сервер Go, который генерирует ключ RSA и затем отправляет его моему клиенту C ++ в форме PKCS#1, ASN.1 DER
. (https://godoc.org/crypto/x509#MarshalPKCS1PublicKey)
Сегодня я перепробовал кучу вещей, но ни один из них не подошел. После того, как я наконец смог, возможно, получить байты в BufferedTransformation
для использования PEM_Load
, я закодировал байты в Base64 и вручную добавил текст верхнего и нижнего колонтитула. Затем я столкнулся с «ошибкой декодирования BER», и теперь я застрял и не уверен, что то, что я создал, даже действительный ключ.
и вот полный код:
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <boost/asio.hpp>
#include <cryptopp/pem.h>
#include <cryptopp/rsa.h>
#include <cryptopp/osrng.h>
#include <cryptopp/base64.h>
#include <cryptopp/dsa.h>
using boost::asio::ip::tcp;
using namespace CryptoPP;
enum { max_length = 1024 };
int main( int argc, char* argv[] ) {
RSA::PrivateKey rsa_private;
AutoSeededRandomPool random;
rsa_private.GenerateRandomWithKeySize( random, 2048 );
auto rsa_public = RSA::PublicKey( rsa_private );
try {
boost::asio::io_context io_context;
tcp::socket s( io_context );
tcp::resolver resolver( io_context );
boost::asio::connect( s, resolver.resolve( "127.0.0.1", "9999" ));
int headersize;
size_t reply_length = boost::asio::read( s,
boost::asio::buffer( &headersize, sizeof(headersize ) ) );
printf( "Got header with size %i\n", headersize );
std::vector<CryptoPP::byte> RSA_PUB(headersize);
size_t read_size = boost::asio::read( s,
boost::asio::buffer( RSA_PUB.data(), headersize ) );
RSA::PublicKey testpub;
Base64Encoder encoder;
encoder.Put( RSA_PUB.data( ), RSA_PUB.size( ) );
encoder.MessageEnd( );
std::string encoded;
auto encoded_size = encoder.MaxRetrievable( );
if ( encoded_size ) {
encoded.resize( encoded_size );
encoder.Get( ( byte* )&encoded[ 0 ], encoded.size( ) );
}
encoded.insert( 0, "-----BEGIN PUBLIC KEY-----\n" );
encoded.append( "-----END PUBLIC KEY-----" );
//ArraySource( RSA_PUB.data( ), RSA_PUB.size( ), true );
CryptoPP::ByteQueue test;
test.Put( (byte*)encoded.data( ), encoded.size( ) );
test.MessageEnd( );
PEM_Load( test, testpub );
//std::cout.write( RSA_PUB.data( ), RSA_PUB.size( ) );
} catch ( std::exception& e ) {
std::cerr << "Exception: " << e.what( ) << "\n";
}
std::cin.get( );
return 0;
}
Обновление: сегодня я пошел дальше и сохранил сгенерированный ключ в файл из Crypto ++, затем сохранил ключ, сгенерированный из Go, и сравнил их: Изображение и на его основе я вижу, что формат очень похож, так что я, по крайней мере, не так уж и далек. Мой следующий шаг - найти и использовать программное обеспечение для проверки формата, поскольку я видел, что он упоминался в прошлом.
Обновление 2: Совершенно очевидно, что MarshalPKCS1PublicKey
не учитывает то, что я бы назвал заголовок из данных и сразу переходит к фактическому значению. Не знаю, как это решить. Спрашивать в разладе Go.