My IV's are completely randomized for security, however, I'm not sure If I'm
loading them in/out correctly.
I get the: StreamTransformationFilter: ciphertext length is not a multiple
of block size error.
CODE:
int xxz568::AESEncrypt(std::string key, std::string input, std::string
&output) {
byte keyB[32], ivB[AES::BLOCKSIZE];
std::string hashKey = sha1(key).substr(0, 32);
memcpy(keyB, hashKey.c_str(), 32);
//
memcpy(ivB, generateRandLen(), 16);
//
std::string hold, final, hexVec, decVec;
HexEncode((const char *)ivB, hexVec);
cout << "IV: " << ivB << " | " << hexVec << endl;
output = hexVec.substr(0, 32);
//convert output back to binary for usage as the initVector
HexDecode(output, decVec);
//store dec Vec in the iv slot
memcpy(ivB, decVec.c_str(), 16);
StringSink* sink = new StringSink(hold);
CBC_Mode<AES>::Encryption aes(keyB, sizeof(keyB), ivB);
StreamTransformationFilter* aes_enc = new StreamTransformationFilter(aes,
sink);
StringSource cipher(input, true, aes_enc);
//convert to a hash
HexEncode(hold, final);
output += final;
//
return 1;
}
int xxz568::AESDecrypt(std::string key, std::string input, std::string
&output) {
std::string bin, store2, init, test;
HexDecode(input, bin);
cout << "DEC: " << bin << endl;
try{
byte keyB[32], iv[AES::BLOCKSIZE];
std::string hashKey = sha1(key).substr(0, 32);
memcpy(keyB, hashKey.c_str(), 32);
//obtain IV
init.assign(bin.substr(0, 16));
memcpy(iv, init.c_str(), 16);
HexEncode(init, test);
store2.assign(bin.substr(16, bin.length()));
cout << "IV: " << init << " | " << test << endl;
//
StringSink* sink = new StringSink(output);
CBC_Mode<AES>::Decryption aes(keyB, sizeof(keyB), iv);
StreamTransformationFilter* aes_enc = new
StreamTransformationFilter(aes, sink);
StringSource cipher(store2, true, aes_enc);
}
catch(CryptoPP::Exception e) {
cout << e.GetWhat() << endl;
output = "Decrypt Error:";
output.append(e.GetWhat());
}
return 1;
}
byte * xxz568::generateRandLen() {
AutoSeededRandomPool rng;
byte randLen[16];
rng.GenerateBlock(randLen, 16);
//
return randLen;
}
int xxz568::HexEncode(std::string input, std::string &output) {
CryptoPP::StringSource foo(input, true,
new CryptoPP::HexEncoder(
new CryptoPP::StringSink(output), false));
return 1;
}
int xxz568::HexDecode(std::string input, std::string &output) {
CryptoPP::StringSource foo(input, true,
new CryptoPP::HexDecoder(
new CryptoPP::StringSink(output)));
return 1;
}
--
View this message in context: http://old.nabble.com/AES-Problem-tp31186698p31186698.html
Sent from the Crypto++ Users mailing list archive at Nabble.com.
1. It looks as though you might be using a truncated SHA1 hash of a
password as an AES key. That's a serious security hole and there's no
good reason to do that. Please use a PBKDF. If I'm reading this wrong
or you don't understand this comment, please reply with an explanation
of what you're doing, because I don't understand your code and all my
commentary is likely off the mark.
2. Don't hex decode into a string unless what was encoded was a proper
string to begin with. If i'm reading your code right, I'd predict that
any time one of your randomly generated IV bytes is a zero, you're
getting uninitialized memory in your IV and (possibly) failing. It's
not a lock that you'll fail every time, but I'd suspect that every
time you fail there's a zero in that buffer.
For the sake of illustration, let's imagine a 4-byte random IV:
// unsigned char[] ivB = { 0xba, 0xdf, 0x00, 0x0d};
HexEncode((const char *)ivB, hexVec);
// hexVec = "badf00d";
HedDecode(hexVec,decVec)
// decVec = "ºß";
// the bytes in decVec will be {0xba, 0xdf, 0x00, UNDEFINED}
// because 0x00 is the terminator for an ASCII string
memcpy(ivB,decVec.c_str(),4);
// ivB will now be {0xba, 0xdf, 0x00, 0x??} where ?? comes from
whatever uninitialized memory was there after the internal
representation. Ideally, this should crash, but that's probabilistic,
not deterministic.
Hope this helps,
Geoff
I'm not quite sure what is meant in #1, can you provide an example?
As for #2, all data output must be in hex, ASCII is not allowed by the
program. So, how would I go about fixing this to be correct? Would usage of
Base64 Encoding over the IV/String work? because B64 is acceptable.
--
View this message in context: http://old.nabble.com/AES-Problem-tp31186698p31192117.html
> I'm not quite sure what is meant in #1, can you provide an example?
>
I'm on a mobile at the moment and it's too cumbersome for me to
search, copy and paste. Just grep -i pbkdf validat*.cpp within the
crypto++ source distribution. You'll find an example of using one.
> As for #2, all data output must be in hex, ASCII is not allowed by the
> program. So, how would I go about fixing this to be correct? Would usage of
> Base64 Encoding over the IV/String work? because B64 is acceptable.
It doesn't matter how you encode the output or IV. Encode them in
whatever way is suitable for your transport. That's not the problem.
The problem is decoding them into string types that aren't meant to
hold arbitrary binary data. (Sorry... I thought my commented snippet
illustrated that.) Decode them into an array of bytes instead. The
SecByteBlock type in crypto++ should be convenient for this kind of
thing.
Good luck.
Geoff
So, I need to know how to use my current hexDecode function to instead of
outputting to a std::String, to be a CryptoPP::SecByteBlock, how can I
adjust my current code to fit this?
I've never used a PBKDF before, nor can find anything in the validat# files
to help me, is there any sample code out there that can help me do so,
keeping in mind that AES-256 requires the 32 bit key length.
--
View this message in context: http://old.nabble.com/AES-Problem-tp31186698p31216023.html
int xxz568::AESDecrypt(std::string key, std::string input, std::string
&output) {
std::string store2, init, hexDec;
CryptoPP::SecByteBlock test;
test.Grow(16);
try{
byte keyB[32];
std::string hashKey = sha1(key).substr(0, 32);
memcpy(keyB, hashKey.c_str(), 32);
//obtain IV
init.assign(input.substr(0, 16));
HexDecodeintoByte(init, test, 16);
cout << "Byte Decoded: " << test << endl;
//obtain the remaining piece
store2.assign(input.substr(16, input.length()));
HexDecode(store2, hexDec);
cout << "Finishing Decode: " << store2 << " -> DECD: " << hexDec << endl;
//
StringSink* sink = new StringSink(output);
CBC_Mode<AES>::Decryption aes(keyB, sizeof(keyB), test);
StreamTransformationFilter* aes_enc = new
StreamTransformationFilter(aes, sink);
StringSource cipher(hexDec, true, aes_enc);
}
catch(CryptoPP::Exception e) {
cout << e.GetWhat() << endl;
output = "Decrypt Error:";
output.append(e.GetWhat());
}
return 1;
}
int xxz568::HexDecodeintoByte(std::string input, CryptoPP::SecByteBlock
&output, int size) {
CryptoPP::StringSource foo(input, true,
new CryptoPP::HexDecoder(
new CryptoPP::ArraySink(output, size)));
return 1;
}
--
View this message in context: http://old.nabble.com/AES-Problem-tp31186698p31224154.html
Reply used to naturally go to the list, I thought. Now it seems
Reply-all is required?
Geoff
---------- Forwarded message ----------
From: Geoff Beier <geoff...@gmail.com>
Date: Thu, Mar 24, 2011 at 01:07
Subject: Re: AES Problem
To: "Robert F." <rfri...@phantomdev.net>
You'll need to change your encryption function too. You've got a round
trip through your old hex encode/decode routines in there.
I whacked together a quick and dirty sample that starts off with a
password and generates a random salt and IV. It uses PBKDF2 to derive
a key suitable for AES from the password and salt, then uses CBC mode
to encrypt a message with that derived key.
It then encodes ciphertext, salt and IV using the Hex Encoder and
prints them. Then it decodes salt and IV, re-runs the key derivation
function with the decoded salt and IV, uses that re-generated key to
decrypt the encoded ciphertext that it just printed.
I did compile and execute the code, but it was put together *very*
quickly and lacks error checking, etc. It should make it easy to
understand how the key derivation function works and how these filters
all hang together.
My sample is here:
http://pastebin.com/sVq5JneG
That code is as-is, no warranties. You can, of course, do what you
want with that code. I'd particularly encourage you to read it
carefully, understand it, find and fix any bugs, and write up your
understanding in the crypto++ wiki so others can find it easily :-)
When I run the test program that I get from compiling that program,
here is its output:
http://pastebin.com/NwjBdPhw
Good luck, and I hope this helps.
Geoff
Thanks!
> --
> You received this message because you are subscribed to the "Crypto++
> Users" Google Group.
> To unsubscribe, send an email to
> cryptopp-user...@googlegroups.com.
> More information about Crypto++ and this group is available at
> http://www.cryptopp.com.
>
>
--
View this message in context: http://old.nabble.com/AES-Problem-tp31186698p31324770.html