我有一个问题指的是这个问题中的加密代码: Crypto++ encrypt and decrypt in two different c++ programs
如果我想使用自定义键/iv,我该怎么做?
我有一个问题指的是这个问题中的加密代码: Crypto++ encrypt and decrypt in two different c++ programs
如果我想使用自定义键/iv,我该怎么做?
If I want to use a custom key/iv, how can I do this?
Just plug it into a cipher with a mode. There are plenty of modes to choose from, but you should use an authenticated encryption mode like EAX, CCM or GCM. See Category:Mode for discussion of the modes in Crypto++.
The code below takes a password or secret, keys a cipher, and then encrypts and encodes a message. Next, it decodes the encrypted message. Finally it prints some of the parameters.
try {
// KDF parameters
string password = "Super secret password";
unsigned int iterations = 15000;
char purpose = 0; // unused by Crypto++
// 32 bytes of derived material. Used to key the cipher.
// 16 bytes are for the key, and 16 bytes are for the iv.
SecByteBlock derived(32);
// KDF function
PKCS5_PBKDF2_HMAC<SHA256> kdf;
kdf.DeriveKey(derived.data(), derived.size(), purpose, (byte*)password.data(), password.size(), NULL, 0, iterations);
// Encrypt a secret message
string plaintext = "Attack at dawn", ciphertext, recovered;
// Key the cipher
EAX<AES>::Encryption encryptor;
encryptor.SetKeyWithIV(derived.data(), 16, derived.data() + 16, 16);
AuthenticatedEncryptionFilter ef(encryptor, new StringSink(ciphertext));
ef.Put((byte*)plaintext.data(), plaintext.size());
ef.MessageEnd();
// Key the cipher
EAX<AES>::Decryption decryptor;
decryptor.SetKeyWithIV(derived.data(), 16, derived.data() + 16, 16);
AuthenticatedDecryptionFilter df(decryptor, new StringSink(recovered));
df.Put((byte*)ciphertext.data(), ciphertext.size());
df.MessageEnd();
// Done with encryption and decryption
// Encode various parameters
HexEncoder encoder;
string key, iv, cipher;
encoder.Detach(new StringSink(key));
encoder.Put(derived.data(), 16);
encoder.MessageEnd();
encoder.Detach(new StringSink(iv));
encoder.Put(derived.data() + 16, 16);
encoder.MessageEnd();
encoder.Detach(new StringSink(cipher));
encoder.Put((byte*)ciphertext.data(), ciphertext.size());
encoder.MessageEnd();
// Print stuff
cout << "plaintext: " << plaintext << endl;
cout << "key: " << key << endl;
cout << "iv: " << iv << endl;
cout << "ciphertext: " << cipher << endl;
cout << "recovered: " << recovered << endl;
}
catch(CryptoPP::Exception& ex)
{
cerr << ex.what() << endl;
}
A run of the program produces the following output.
$ ./cryptopp-test.exe
plaintext: Attack at dawn
key: 7A8C7732898FB687669CB7DBEFBDD789
iv: 0AA980BABE72797E415C9B8979BF30EF
ciphertext: 197D0BD1A12577393AD1B1696B75D0FC6B8A142CF15B5F887AA965CE75F0
recovered: Attack at dawn
Even better, use an Integrated Encryption Scheme. Crypto++ provides two of them. The first is Elliptic Curve Integrated Encryption Scheme which operates over fields of elliptic curse. The second is Discrete Logarithm Integrated Encryption Scheme, which operates over the field of integers.
There's a number of non-obvious reason why its "even better", but the big one is its IND-CCA2. Other, more practical ones include: you can't reuse a security context because correct use is built into the system; and padding has been removed which greatly simplifies proofs and avoids potential oracles. The system is also predicated on Discrete Logs, which makes it a Diffie-Hellman based problem and its believed to be hard everywhere.