mirror of
https://github.com/pocoproject/poco.git
synced 2024-12-13 10:32:57 +01:00
backport CipherKey digest changes and tests from develop
This commit is contained in:
parent
b4f1427725
commit
dc2c4dcd27
@ -61,7 +61,8 @@ public:
|
||||
CipherKey(const std::string& name,
|
||||
const std::string& passphrase,
|
||||
const std::string& salt = "",
|
||||
int iterationCount = DEFAULT_ITERATION_COUNT);
|
||||
int iterationCount = DEFAULT_ITERATION_COUNT,
|
||||
const std::string& digest = "md5");
|
||||
/// Creates a new CipherKeyImpl object using the given
|
||||
/// cipher name, passphrase, salt value and iteration count.
|
||||
|
||||
|
@ -54,7 +54,8 @@ public:
|
||||
CipherKeyImpl(const std::string& name,
|
||||
const std::string& passphrase,
|
||||
const std::string& salt,
|
||||
int iterationCount);
|
||||
int iterationCount,
|
||||
const std::string& digest);
|
||||
/// Creates a new CipherKeyImpl object, using
|
||||
/// the given cipher name, passphrase, salt value
|
||||
/// and iteration count.
|
||||
@ -116,6 +117,7 @@ private:
|
||||
|
||||
private:
|
||||
const EVP_CIPHER* _pCipher;
|
||||
const EVP_MD* _pDigest;
|
||||
std::string _name;
|
||||
ByteVec _key;
|
||||
ByteVec _iv;
|
||||
|
@ -19,8 +19,12 @@ namespace Poco {
|
||||
namespace Crypto {
|
||||
|
||||
|
||||
CipherKey::CipherKey(const std::string& name, const std::string& passphrase, const std::string& salt, int iterationCount):
|
||||
_pImpl(new CipherKeyImpl(name, passphrase, salt, iterationCount))
|
||||
CipherKey::CipherKey(const std::string& name,
|
||||
const std::string& passphrase,
|
||||
const std::string& salt,
|
||||
int iterationCount,
|
||||
const std::string &digest):
|
||||
_pImpl(new CipherKeyImpl(name, passphrase, salt, iterationCount, digest))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -28,8 +28,10 @@ namespace Crypto {
|
||||
CipherKeyImpl::CipherKeyImpl(const std::string& name,
|
||||
const std::string& passphrase,
|
||||
const std::string& salt,
|
||||
int iterationCount):
|
||||
int iterationCount,
|
||||
const std::string& digest):
|
||||
_pCipher(0),
|
||||
_pDigest(0),
|
||||
_name(name),
|
||||
_key(),
|
||||
_iv()
|
||||
@ -40,6 +42,12 @@ CipherKeyImpl::CipherKeyImpl(const std::string& name,
|
||||
|
||||
if (!_pCipher)
|
||||
throw Poco::NotFoundException("Cipher " + name + " was not found");
|
||||
|
||||
_pDigest = EVP_get_digestbyname(digest.c_str());
|
||||
|
||||
if (!_pDigest)
|
||||
throw Poco::NotFoundException("Digest " + name + " was not found");
|
||||
|
||||
_key = ByteVec(keySize());
|
||||
_iv = ByteVec(ivSize());
|
||||
generateKey(passphrase, salt, iterationCount);
|
||||
@ -50,6 +58,7 @@ CipherKeyImpl::CipherKeyImpl(const std::string& name,
|
||||
const ByteVec& key,
|
||||
const ByteVec& iv):
|
||||
_pCipher(0),
|
||||
_pDigest(0),
|
||||
_name(name),
|
||||
_key(key),
|
||||
_iv(iv)
|
||||
@ -65,6 +74,7 @@ CipherKeyImpl::CipherKeyImpl(const std::string& name,
|
||||
|
||||
CipherKeyImpl::CipherKeyImpl(const std::string& name):
|
||||
_pCipher(0),
|
||||
_pDigest(0),
|
||||
_name(name),
|
||||
_key(),
|
||||
_iv()
|
||||
@ -157,7 +167,7 @@ void CipherKeyImpl::generateKey(
|
||||
// Now create the key and IV, using the MD5 digest algorithm.
|
||||
int keySize = EVP_BytesToKey(
|
||||
_pCipher,
|
||||
EVP_md5(),
|
||||
_pDigest ? _pDigest : EVP_md5(),
|
||||
(salt.empty() ? 0 : saltBytes),
|
||||
reinterpret_cast<const unsigned char*>(password.data()),
|
||||
static_cast<int>(password.size()),
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "Poco/Crypto/CryptoStream.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/Base64Encoder.h"
|
||||
#include "Poco/HexBinaryEncoder.h"
|
||||
#include <sstream>
|
||||
|
||||
|
||||
@ -124,6 +125,39 @@ void CryptoTest::testEncryptDecryptWithSalt()
|
||||
}
|
||||
|
||||
|
||||
void CryptoTest::testEncryptDecryptWithSaltSha1()
|
||||
{
|
||||
Cipher::Ptr pCipher = CipherFactory::defaultFactory().createCipher(
|
||||
CipherKey("aes256", "simplepwd", "Too much salt", 2000, "sha1"));
|
||||
Cipher::Ptr pCipher2 = CipherFactory::defaultFactory().createCipher(
|
||||
CipherKey("aes256", "simplepwd", "Too much salt", 2000, "sha1"));
|
||||
|
||||
for (std::size_t n = 1; n < MAX_DATA_SIZE; n++)
|
||||
{
|
||||
std::string in(n, 'x');
|
||||
std::string out = pCipher->encryptString(in, Cipher::ENC_NONE);
|
||||
std::string result = pCipher2->decryptString(out, Cipher::ENC_NONE);
|
||||
assert (in == result);
|
||||
}
|
||||
|
||||
for (std::size_t n = 1; n < MAX_DATA_SIZE; n++)
|
||||
{
|
||||
std::string in(n, 'x');
|
||||
std::string out = pCipher->encryptString(in, Cipher::ENC_BASE64);
|
||||
std::string result = pCipher2->decryptString(out, Cipher::ENC_BASE64);
|
||||
assert (in == result);
|
||||
}
|
||||
|
||||
for (std::size_t n = 1; n < MAX_DATA_SIZE; n++)
|
||||
{
|
||||
std::string in(n, 'x');
|
||||
std::string out = pCipher->encryptString(in, Cipher::ENC_BINHEX);
|
||||
std::string result = pCipher2->decryptString(out, Cipher::ENC_BINHEX);
|
||||
assert (in == result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CryptoTest::testEncryptDecryptDESECB()
|
||||
{
|
||||
Cipher::Ptr pCipher = CipherFactory::defaultFactory().createCipher(CipherKey("des-ecb", "password"));
|
||||
@ -167,6 +201,33 @@ void CryptoTest::testPassword()
|
||||
}
|
||||
|
||||
|
||||
void CryptoTest::testPasswordSha1()
|
||||
{
|
||||
// the test uses 1 iteration, as the openssl executable does not allow to set a custom number
|
||||
// of iterations
|
||||
CipherKey key("aes256", "password", "saltsalt", 1, "sha1");
|
||||
|
||||
std::ostringstream keyStream;
|
||||
Poco::HexBinaryEncoder hexKeyEnc(keyStream);
|
||||
hexKeyEnc.write(reinterpret_cast<const char*>(&key.getKey()[0]), key.keySize());
|
||||
hexKeyEnc.close();
|
||||
std::string hexKey = keyStream.str();
|
||||
|
||||
std::ostringstream ivStream;
|
||||
Poco::HexBinaryEncoder hexIvEnc(ivStream);
|
||||
hexIvEnc.write(reinterpret_cast<const char*>(&key.getIV()[0]), key.ivSize());
|
||||
hexIvEnc.close();
|
||||
std::string hexIv = ivStream.str();
|
||||
|
||||
// got Hex value for key and iv using:
|
||||
// openssl enc -e -a -md sha1 -aes256 -k password -S 73616c7473616c74 -P
|
||||
// (where "salt" == 73616c74 in Hex, doubled for an 8 bytes salt, openssl padds the salt with 0
|
||||
// whereas Poco's implementation padds with the existing bytes using a modulo operation)
|
||||
assert (hexIv == "c96049b0edc0b67af61ecc43d3de8898");
|
||||
assert (hexKey == "cab86dd6261710891e8cb56ee3625691a75df344f0bff4c12cf3596fc00b39c7");
|
||||
}
|
||||
|
||||
|
||||
void CryptoTest::testEncryptInterop()
|
||||
{
|
||||
Cipher::Ptr pCipher = CipherFactory::defaultFactory().createCipher(CipherKey("aes256", "password", "salt"));
|
||||
@ -268,8 +329,10 @@ CppUnit::Test* CryptoTest::suite()
|
||||
|
||||
CppUnit_addTest(pSuite, CryptoTest, testEncryptDecrypt);
|
||||
CppUnit_addTest(pSuite, CryptoTest, testEncryptDecryptWithSalt);
|
||||
CppUnit_addTest(pSuite, CryptoTest, testEncryptDecryptWithSaltSha1);
|
||||
CppUnit_addTest(pSuite, CryptoTest, testEncryptDecryptDESECB);
|
||||
CppUnit_addTest(pSuite, CryptoTest, testPassword);
|
||||
CppUnit_addTest(pSuite, CryptoTest,testPasswordSha1);
|
||||
CppUnit_addTest(pSuite, CryptoTest, testEncryptInterop);
|
||||
CppUnit_addTest(pSuite, CryptoTest, testDecryptInterop);
|
||||
CppUnit_addTest(pSuite, CryptoTest, testStreams);
|
||||
|
@ -31,9 +31,11 @@ public:
|
||||
|
||||
void testEncryptDecrypt();
|
||||
void testEncryptDecryptWithSalt();
|
||||
void testEncryptDecryptWithSaltSha1();
|
||||
void testEncryptDecryptDESECB();
|
||||
void testStreams();
|
||||
void testPassword();
|
||||
void testPasswordSha1();
|
||||
void testEncryptInterop();
|
||||
void testDecryptInterop();
|
||||
void testCertificate();
|
||||
|
Loading…
Reference in New Issue
Block a user