ElGamal加密示例? [英] ElGamal encryption example?
问题描述
我对提出这个问题的n00bishness提前道歉,但我一直困扰着年龄,我正在努力弄明白下一步做什么。基本上,我试图对一些数据执行ElGamal加密。我已经被给予短暂的密钥对和第二静态密钥的公共部分,以及一些数据。如果我的理解是正确的,这就是我需要执行的加密,但我很难弄清楚如何使用Crypto ++。
我一直在寻找例子,但我可以在Google上找到零。 Ohloh不是有用的,因为我只是回到了cryptopp ElGamal源文件的无尽页面,我似乎无法找出(我是相对新的使用Crypto ++,直到大约3天前没有听说过ElGamal)。
我能找到的最近的例子来自CryptoPP包本身,如下:
bool ValidateElGamal()
{
cout< \\\
ElGamal validation suite running ... \\\
\\\
;
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)&&通过;
}
return pass;
}
然而,这似乎并不能帮助我,不知道如何插入我已经计算的值。我不知道如果我在努力与我如何Elgamal的工作(完全可能的),或者如果我只是一个白痴,当谈到使用CryptoPP我有的东西。任何人都可以帮助我指出正确的方向?
短暂的密钥对和第二个静态密钥,以及一些数据。
我们不能真正地帮助你,没有什么是应该做什么。
临时密钥对可能用于模拟密钥交换,而静态密钥对于签署临时交换是长期的。除此之外,它的任何人的猜测是怎么回事。
你会碰巧知道钥匙是什么?是临时密钥Diffie-Hellman密钥和静态密钥ElGamal签名密钥?
对于加密示例,我将进行一些操作,并使用 RSA加密示例并将其移植到ElGamal。这与复制和粘贴一样困难,因为RSA加密和 ElGamal加密都遵守到 PK_Encryptor
和 PK_Decryptor
接口。请参阅 PK_Encryptor
和详细信息 PK_Decryptor
。 (请记住,您可能需要一个ElGamal或Nyberg-Rueppel(NR)签名示例)。
Crypto ++有一个基于ElGamal的密码系统。密码系统将在对称密钥下加密大块纯文本,然后在ElGamal密钥下加密对称密钥。我不知道它遵循什么标准,虽然(可能IEEE的P1363)。在 SymmetricEncrypt 和 SymmetricDecrypt
elgamal_8h_source.htmlrel =nofollow> elgamal.h 。
键大小是人为小的,所以程序运行很快。 ElGamal是一个离散对数问题,因此在实践中它的密钥大小应该是2048位或更高。 2048位由ECRYPT(亚洲),ISO / IEC(全球),NESSIE(欧洲)和NIST(美国)祝福。
如果您需要保存/持续/加载您生成的密钥,然后查看Crypto ++ wiki上的密钥和格式。简单的回答是调用 decryptor.Save()
和 decryptor.Load()
;并远离 {BER | DER}
编码。
如果需要,您可以使用标准 string
,而不是 SecByteBlock
。如果您有兴趣通过 cout
和朋友在终端上打印东西, string
最后,现在在Crypto ++ Wiki上有一个页面,其中包含了下面程序的源代码。请参阅Crypto ++的 ElGamal加密。
#include< iostream>
using std :: cout;
using std :: cerr;
using std :: endl;
#include< cryptopp / osrng.h>
使用CryptoPP :: AutoSeededRandomPool;
#include< cryptopp / secblock.h>
使用CryptoPP :: SecByteBlock;
#include< cryptopp / elgamal.h>
使用CryptoPP :: ElGamal;
使用CryptoPP :: ElGamalKeys;
#include< cryptopp / cryptlib.h>
使用CryptoPP :: DecodingResult;
int main(int argc,char * argv [])
{
///////////////////// ///////////////////////////
//生成键
AutoSeededRandomPool rng;
cout<< 生成私钥,这可能需要一些时间...< endl
ElGamal :: Decryptor decryptor;
decryptor.AccessKey()。GenerateRandomWithKeySize(rng,512);
const ElGamalKeys :: PrivateKey& privateKey = decryptor.AccessKey();
ElGamal ::加密器加密器(解密器);
const PublicKey& publicKey = encryptor.AccessKey();
////////////////////////////////////////// //////
//保护的秘密
static const int SECRET_SIZE = 16;
SecByteBlock plaintext(SECRET_SIZE);
memset(plaintext,'A',SECRET_SIZE);
////////////////////////////////////////// //////
//加密
//现在有一个具体的对象,我们可以验证
assert(0!= encryptor.FixedMaxPlaintextLength());
assert(plaintext.size()< = encryptor.FixedMaxPlaintextLength());
//创建密文空间
size_t ecl = encryptor.CiphertextLength(plaintext.size());
assert(0!= ecl);
SecByteBlock ciphertext(ecl);
encryptor.Encrypt(rng,plaintext,plaintext.size(),ciphertext);
////////////////////////////////////////// //////
//解密
//现在有一个具体的对象,我们可以检查大小
assert(0!= decryptor.FixedCiphertextLength()) ;
assert(ciphertext.size()< = decryptor.FixedCiphertextLength());
//创建恢复的文本空间
size_t dpl = decryptor.MaxPlaintextLength(ciphertext.size());
assert(0!= dpl);
SecByteBlock recover(dpl);
DecodingResult result = decryptor.Decrypt(rng,ciphertext,ciphertext.size(),recovered);
//更多健全检查
assert(result.isValidCoding);
assert(result.messageLength< = decryptor.MaxPlaintextLength(ciphertext.size()));
//此时,我们可以设置恢复的
//数据的大小。直到解密发生(成功),我们
//只知道它的最大大小
recover.resize(result.messageLength);
// SecByteBlock被重载以获得正确的结果
assert(plaintext == recovered);
//如果assert被触发,我们不会得到这么远。
if(plaintext == recovered)
cout<< 恢复的纯文本< endl
else
cout<< 无法恢复纯文本<< endl
return!(plaintext == recovered);
}
您也可以创建解密器
从 PrivateKey
如下:
ElGamalKeys :: PrivateKey k;
k.GenerateRandomWithKeySize(rng,512);
ElGamal :: Decryptor d(k);
...
和加密器
从 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 * /)。
ElGamalKeys :: PrivateKey privateKey2;
privateKey2.Load(FileSource(elgamal.der,true / * pump * /)。
privateKey2.Validate(prng,3);
ElGamal :: Decryptor decryptor(privateKey2);
// ...
键是ASN.1编码的,他们与像Peter Gutmann的 dumpasn1
:
$ ./cryptop- elgamal-keys.exe
生成私钥。这可能需要一些时间...
$ 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
:[另外129个字节被跳过]
265 1:整数3
268 257:整数
: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
:[另外129字节跳过]
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个警告,0个错误。
I apologise in advance for the n00bishness of asking this question, but I've been stuck for ages and I'm struggling to figure out what to do next. Essentially, I am trying to perform ElGamal encryption on some data. I have been given the public part of an ephemeral key pair and a second static key, as well as some data. If my understanding is correct, this is all I need to perform the encryption, but I'm struggling to figure out how using Crypto++.
I've looked endlessly for examples, but I can find literally zero on Google. Ohloh is less than helpful as I just get back endless pages of the cryptopp ElGamal source files, which I can't seem to be able to figure out (I'm relatively new to using Crypto++ and until about 3 days ago hadn't even heard of ElGamal).
The closest I've been able to find as an example comes from the CryptoPP package itself, which is as follows:
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;
}
However, this doesn't really seem to help me much as I'm unaware of how to plug in my already computed values. I am not sure if I'm struggling with my understanding of how Elgamal works (entirely possible) or if I'm just being an idiot when it comes to using what I've got with CryptoPP. Can anyone help point me in the right direction?
I have been given the public part of an ephemeral key pair and a second static key, as well as some data.
We can't really help you here because we know nothing about what is supposed to be done.
The ephemeral key pair is probably for simulating key exchange, and the static key is long term for signing the ephemeral exchange. Other than that, its anybody's guess as to what's going on.
Would you happen to know what the keys are? is the ephemeral key a Diffie-Hellman key and the static key an ElGamal signing key?
If my understanding is correct, this is all I need to perform the encryption, but I'm struggling to figure out how using Crypto++.
For the encryption example, I'm going to cheat a bit and use an RSA encryption example and port it to ElGamal. This is about as difficult as copy and paste because both RSA encryption and ElGamal encryption adhere to the the PK_Encryptor
and PK_Decryptor
interfaces. See the PK_Encryptor
and PK_Decryptor
classes for details. (And keep in mind, you might need an ElGamal or Nyberg-Rueppel (NR) signing example).
Crypto++ has a cryptosystem built on ElGamal. The cryptosystem will encrypt a large block of plain text under a symmetric key, and then encrypt the symmetric key under the ElGamal key. I'm not sure what standard it follows, though (likely IEEE's P1363). See SymmetricEncrypt
and SymmetricDecrypt
in elgamal.h.
The key size is artificially small so the program runs quickly. ElGamal is a discrete log problem, so its key size should be 2048-bits or higher in practice. 2048-bits is blessed by ECRYPT (Asia), ISO/IEC (Worldwide), NESSIE (Europe), and NIST (US).
If you need to save/persist/load the keys you generate, then see Keys and Formats on the Crypto++ wiki. The short answer is to call decryptor.Save()
and decryptor.Load()
; and stay away from the {BER|DER}
encodings.
If you want, you can use a standard string
rather than a SecByteBlock
. The string
will be easier if you are interested in printing stuff to the terminal via cout
and friends.
Finally, there's now a page on the Crypto++ Wiki covering the topic with the source code for the program below. See Crypto++'s ElGamal Encryption.
#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);
}
You can also create the Decryptor
from a PrivateKey
like so:
ElGamalKeys::PrivateKey k;
k.GenerateRandomWithKeySize(rng, 512);
ElGamal::Decryptor d(k);
...
And an Encryptor
from a PublicKey
:
ElGamalKeys::PublicKey pk;
privateKey.MakePublicKey(pk);
ElGamal::Encryptor e(pk);
You can save and load keys to and from disk as follows:
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);
// ...
The keys are ASN.1 encoded, so you can dump them with something like Peter Gutmann's 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.
这篇关于ElGamal加密示例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!