ElGamal加密示例? [英] ElGamal encryption example?

查看:165
本文介绍了ElGamal加密示例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对提出这个问题的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆