RAW RSA шифрование и дешифрование с помощью Crypto ++ - PullRequest
4 голосов
/ 23 марта 2012

Мне нужно установить безопасную связь между ПК и устройством, которое поддерживает шифрование RSA и подпись с SHA1.Поскольку я уже использовал Crypto ++ в другой части своего приложения, я хотел бы также использовать Crypto ++ для этого.

Устройство очень примитивно, но позволяет выполнять программу, которую я пишу на нем.Он имеет встроенные функции необработанных RSA и SHAa;Однако у него очень мало памяти, чтобы быть точным, 2 байта.

Я должен зашифровать и подписать сообщение с ПК.Затем устройство расшифровывает и проверяет сообщение.Затем устройство ответит зашифрованным сообщением и подпишет его.ПК расшифрует сообщение и проверит его позже.Я реализовал необработанное шифрование RSA, подпись и проверку с помощью SHA1 внутри устройства, используя встроенные функции.Сообщения достаточно короткие, чтобы их можно было сделать за один раунд.

Однако я не знаю, как зашифровать сообщение с помощью необработанного RSA с использованием Crypto ++ без участия OAEP или PKCS # 1.Может ли кто-нибудь любезно показать мне пример кода?Спасибо за тонну!

Ответы [ 2 ]

2 голосов
/ 04 октября 2013

Я не знаю, как зашифровать сообщение с помощью необработанного RSA с использованием Crypto ++ без участия OAEP или PKCS # 1.Может ли кто-нибудь любезно показать мне пример кода?

Это достаточно просто, когда вы знаете, где искать: Raw RSA из вики Crypto ++.Код ниже взят со страницы.


Шифрование

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

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

/////////////////////////////////////////////////////////

Integer m, c;
string message = "secret";  

cout << "message: " << message << endl;

// Treat the message as a big endian byte array
m = Integer((const byte *)message.data(), message.size());
cout << "m: " << hex << m << endl;

// Encrypt
c = pubKey.ApplyFunction(m);
cout << "c: " << hex << c << endl;

Расшифровка

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

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

/////////////////////////////////////////////////////////

Integer c(0x3f47c32e8e17e291), r;
string recovered;

// Decrypt
r = privKey.CalculateInverse(prng, c);
cout << "r: " << hex << r << endl;

// Round trip the message
size_t req = r.MinEncodedSize();
recovered.resize(req);
r.Encode((byte *)recovered.data(), recovered.size());

cout << "recovered: " << recovered << endl; 

Вот пример выходных данных:

$ ./cryptopp-raw-rsa.exe
message: secret
m: 736563726574h
c: 3f47c32e8e17e291h
r: 736563726574h
recovered: secret

Существует одно предупреждение: c = m ^ e mod n, поэтому существуют некоторые ограничения на размер обычного текста и размер зашифрованного текста.По существу, m и c должны быть меньше, чем n.В этом примере замена строки secret на now is the time for all good men to come to the aide of their country завершится неудачно, поскольку ее значение больше n при преобразовании в Integer.

Максимальный размер обычного текста можно получить с помощью функции * 1036.* и максимальный размер зашифрованного текста с MaxImage().


Я должен зашифровать и подписать сообщение с ПК.Затем устройство расшифровывает и проверяет сообщение.Затем устройство ответит зашифрованным сообщением и подпишет его.ПК расшифрует сообщение и проверит его позже.

На первый взгляд это похоже на повторные атаки.Вам может понадобиться протокол с защитой.

1 голос
/ 23 марта 2012

Вот демонстрационная функция, которую я написал, когда впервые применил шифрование и дешифрование RSA с помощью Crypto ++. Я написал это просто, чтобы понять основы. Надеюсь, это поможет:

#include <cryptopp/files.h>
#include <cryptopp/modes.h>
#include <cryptopp/osrng.h>
#include <cryptopp/rsa.h>
#include <cryptopp/sha.h>

void rsa_examples()
{
    // Keys created here may be used by OpenSSL.
    //
    // openssl pkcs8 -in key.der -inform DER -out key.pem -nocrypt 
    // openssl rsa -in key.pem -check

    CryptoPP::AutoSeededRandomPool rng;

    // Create a private RSA key and write it to a file using DER.
    CryptoPP::RSAES_OAEP_SHA_Decryptor priv( rng, 4096 );
    CryptoPP::TransparentFilter privFile( new CryptoPP::FileSink("rsakey.der") );
    priv.DEREncode( privFile );
    privFile.MessageEnd();

    // Create a private RSA key and write it to a string using DER (also write to a file to check it with OpenSSL).
    std::string the_key;
    CryptoPP::RSAES_OAEP_SHA_Decryptor pri( rng, 2048 );
    CryptoPP::TransparentFilter privSink( new CryptoPP::StringSink(the_key) );
    pri.DEREncode( privSink );
    privSink.MessageEnd();

    std::ofstream file ( "key.der", std::ios::out | std::ios::binary );
    file.write( the_key.data(), the_key.size() );
    file.close();

    // Example Encryption & Decryption
    CryptoPP::InvertibleRSAFunction params;
    params.GenerateRandomWithKeySize( rng, 1536 );

    std::string plain = "RSA Encryption", cipher, decrypted_data;

    CryptoPP::RSA::PrivateKey privateKey( params );
    CryptoPP::RSA::PublicKey publicKey( params );

    CryptoPP::RSAES_OAEP_SHA_Encryptor e( publicKey );
    CryptoPP::StringSource( plain, true, new CryptoPP::PK_EncryptorFilter( rng, e, new CryptoPP::StringSink( cipher )));

    CryptoPP::RSAES_OAEP_SHA_Decryptor d( privateKey );
    CryptoPP::StringSource( cipher, true, new CryptoPP::PK_DecryptorFilter( rng, d, new CryptoPP::StringSink( decrypted_keydata )));

    assert( plain == decrypted_data );
}
...