Пример шифрования ElGamal?

Я заранее извиняюсь за то, что задал этот вопрос, но я застрял целую вечность и изо всех сил пытаюсь понять, что делать дальше. По сути, я пытаюсь выполнить шифрование ElGamal для некоторых данных. Мне дали открытую часть пары эфемерных ключей и второй статический ключ, а также некоторые данные. Если мое понимание правильное, это все, что мне нужно для шифрования, но я пытаюсь понять, как использовать Crypto ++.

Я бесконечно искал примеры, но я могу найти буквально ноль в Google. Охлох менее чем полезен, так как я просто возвращаю бесконечные страницы исходных файлов cryptopp ElGamal, которые я не могу понять (я относительно новичок в использовании Crypto ++ и до тех пор, пока около 3 дней назад даже не слышал об ЭльГамале).

Наиболее близкий пример, который я смог найти, взят из самого пакета CryptoPP, а именно:

bool ValidateElGamal()
{
cout << "\nElGamal validation suite running...\n\n";
bool pass = true;
{
FileSource fc("TestData/elgc1024.dat", true, new HexDecoder);
ElGamalDecryptor privC(fc);
ElGamalEncryptor pubC(privC);
privC.AccessKey().Precompute();
ByteQueue queue;
privC.AccessKey().SavePrecomputation(queue);
privC.AccessKey().LoadPrecomputation(queue);

pass = CryptoSystemValidate(privC, pubC) && pass;
}
return pass;
}

Тем не менее, это не очень мне помогает, так как я не знаю, как подключить уже вычисленные значения. Я не уверен, борюсь ли я со своим пониманием того, как работает Elgamal (вполне возможно), или я просто идиот, когда дело доходит до использования того, что у меня есть с CryptoPP. Может ли кто-нибудь помочь направить меня в правильном направлении?

2

Решение

Мне дали открытую часть пары эфемерных ключей и второй статический ключ, а также некоторые данные.

Мы не можем вам здесь помочь, потому что мы ничего не знаем о том, что должно быть сделано.

Пара эфемерных ключей, вероятно, предназначена для имитации обмена ключами, а статический ключ является долгосрочным для подписания эфемерного обмена. Кроме этого, никто не может догадаться, что происходит.

Вы случайно не знаете, что это за ключи? эфемерный ключ — это ключ Диффи-Хеллмана, а статический ключ — ключ подписи Эль-Гамаля?


Если мое понимание правильное, это все, что мне нужно для шифрования, но я пытаюсь понять, как использовать Crypto ++.

Для примера шифрования я собираюсь немного обмануть и использовать Пример шифрования RSA и перенести его в Эль-Гамаль. Это примерно так же сложно, как копирование и вставка, потому что и шифрование RSA, и Эль-Гамальское шифрование придерживаться PK_Encryptor а также PK_Decryptor интерфейсы. Увидеть PK_Encryptor а также PK_Decryptor классы для деталей. (И имейте в виду, вам может понадобиться пример подписания Эль-Гамаля или Нюберга-Рюппеля (НР)).

Crypto ++ имеет криптосистему, построенную на ElGamal. Криптосистема будет шифровать большой блок простого текста под симметричным ключом, а затем шифровать симметричный ключ под ключом Эль-Гамаля. Хотя я не уверен, к какому стандарту это относится (вероятно, к IEEE P1363). Увидеть SymmetricEncrypt а также SymmetricDecrypt в elgamal.h.

Размер ключа искусственно мал, поэтому программа работает быстро. ElGamal — это проблема дискретного журнала, поэтому на практике его размер ключа должен быть 2048 бит или выше. 2048-биты благословлены ECRYPT (Азия), ISO / IEC (по всему миру), NESSIE (Европа) и NIST (США).

Если вам нужно сохранить / сохранить / загрузить ключи, которые вы генерируете, то смотрите Ключи и форматы на Crypto ++ вики. Краткий ответ — позвонить decryptor.Save() а также decryptor.Load(); и держаться подальше от {BER|DER} кодировок.

Если вы хотите, вы можете использовать стандарт string а не SecByteBlock, string будет проще, если вы заинтересованы в печати материала на терминал через cout и друзья.

Наконец, теперь есть страница на Crypto ++ Wiki, посвященная теме с исходным кодом для программы ниже. Смотрите Crypto ++ Эль-Гамаль Шифрование.

#include <iostream>
using std::cout;
using std::cerr;
using std::endl;

#include <cryptopp/osrng.h>
using CryptoPP::AutoSeededRandomPool;

#include <cryptopp/secblock.h>
using CryptoPP::SecByteBlock;

#include <cryptopp/elgamal.h>
using CryptoPP::ElGamal;
using CryptoPP::ElGamalKeys;

#include <cryptopp/cryptlib.h>
using CryptoPP::DecodingResult;

int main(int argc, char* argv[])
{
////////////////////////////////////////////////
// Generate keys
AutoSeededRandomPool rng;

cout << "Generating private key. This may take some time..." << endl;

ElGamal::Decryptor decryptor;
decryptor.AccessKey().GenerateRandomWithKeySize(rng, 512);
const ElGamalKeys::PrivateKey& privateKey = decryptor.AccessKey();

ElGamal::Encryptor encryptor(decryptor);
const PublicKey& publicKey = encryptor.AccessKey();

////////////////////////////////////////////////
// Secret to protect
static const int SECRET_SIZE = 16;
SecByteBlock plaintext( SECRET_SIZE );
memset( plaintext, 'A', SECRET_SIZE );

////////////////////////////////////////////////
// Encrypt

// Now that there is a concrete object, we can validate
assert( 0 != encryptor.FixedMaxPlaintextLength() );
assert( plaintext.size() <= encryptor.FixedMaxPlaintextLength() );

// Create cipher text space
size_t ecl = encryptor.CiphertextLength( plaintext.size() );
assert( 0 != ecl );
SecByteBlock ciphertext( ecl );

encryptor.Encrypt( rng, plaintext, plaintext.size(), ciphertext );

////////////////////////////////////////////////
// Decrypt

// Now that there is a concrete object, we can check sizes
assert( 0 != decryptor.FixedCiphertextLength() );
assert( ciphertext.size() <= decryptor.FixedCiphertextLength() );

// Create recovered text space
size_t dpl = decryptor.MaxPlaintextLength( ciphertext.size() );
assert( 0 != dpl );
SecByteBlock recovered( dpl );

DecodingResult result = decryptor.Decrypt( rng, ciphertext, ciphertext.size(), recovered );

// More sanity checks
assert( result.isValidCoding );
assert( result.messageLength <= decryptor.MaxPlaintextLength( ciphertext.size() ) );

// At this point, we can set the size of the recovered
//  data. Until decryption occurs (successfully), we
//  only know its maximum size
recovered.resize( result.messageLength );

// SecByteBlock is overloaded for proper results below
assert( plaintext == recovered );

// If the assert fires, we won't get this far.
if(plaintext == recovered)
cout << "Recovered plain text" << endl;
else
cout << "Failed to recover plain text" << endl;

return !(plaintext == recovered);
}

Вы также можете создать Decryptor из PrivateKey вот так:

ElGamalKeys::PrivateKey k;
k.GenerateRandomWithKeySize(rng, 512);
ElGamal::Decryptor d(k);
...

И Encryptor из PublicKey:

ElGamalKeys::PublicKey pk;
privateKey.MakePublicKey(pk);
ElGamal::Encryptor e(pk);

Вы можете сохранять и загружать ключи на диск и с него следующим образом:

ElGamalKeys::PrivateKey privateKey1;
privateKey1.GenerateRandomWithKeySize(prng, 2048);
privateKey1.Save(FileSink("elgamal.der", true /*binary*/).Ref());

ElGamalKeys::PrivateKey privateKey2;
privateKey2.Load(FileSource("elgamal.der", true /*pump*/).Ref());
privateKey2.Validate(prng, 3);

ElGamal::Decryptor decryptor(privateKey2);
// ...

Ключи закодированы в ASN.1, так что вы можете сбросить их с помощью чего-то вроде Питера Гутмана dumpasn1:

$ ./cryptopp-elgamal-keys.exe
Generating private key. This may take some time...
$ dumpasn1 elgamal.der
0 556: SEQUENCE {
4 257:   INTEGER
:     00 C0 8F 5A 29 88 82 8C 88 7D 00 AE 08 F0 37 AC
:     FA F3 6B FC 4D B2 EF 5D 65 92 FD 39 98 04 C7 6D
:     6D 74 F5 FA 84 8F 56 0C DD B4 96 B2 51 81 E3 A1
:     75 F6 BE 82 46 67 92 F2 B3 EC 41 00 70 5C 45 BF
:     40 A0 2C EC 15 49 AD 92 F1 3E 4D 06 E2 89 C6 5F
:     0A 5A 88 32 3D BD 66 59 12 A1 CB 15 B1 72 FE F3
:     2D 19 DD 07 DF A8 D6 4C B8 D0 AB 22 7C F2 79 4B
:     6D 23 CE 40 EC FB DF B8 68 A4 8E 52 A9 9B 22 F1
:             [ Another 129 bytes skipped ]
265   1:   INTEGER 3
268 257:   INTEGER
:     00 BA 4D ED 20 E8 36 AC 01 F6 5C 9C DA 62 11 BB
:     E9 71 D0 AB B7 E2 D3 61 37 E2 7B 5C B3 77 2C C9
:     FC DE 43 70 AE AA 5A 3C 80 0A 2E B0 FA C9 18 E5
:     1C 72 86 46 96 E9 9A 44 08 FF 43 62 95 BE D7 37
:     F8 99 16 59 7D FA 3A 73 DD 0D C8 CA 19 B8 6D CA
:     8D 8E 89 52 50 4E 3A 84 B3 17 BD 71 1A 1D 38 9E
:     4A C4 04 F3 A2 1A F7 1F 34 F0 5A B9 CD B4 E2 7F
:     8C 40 18 22 58 85 14 40 E0 BF 01 2D 52 B7 69 7B
:             [ Another 129 bytes skipped ]
529  29:   INTEGER
:     01 61 40 24 1F 48 00 4C 35 86 0B 9D 02 8C B8 90
:     B1 56 CF BD A4 75 FE E2 8E 0B B3 66 08
:   }

0 warnings, 0 errors.
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]