IV value read from Binary file, is not proper - python-2.7

I have an encrypted binary file of size 256*N bytes.
The last two bytes of the first page(256 length) contains the IV value to decrypt.
If i fetch that using the below code:
infile.seek(240,0)
iv = infile.read(16)
(infile is input file). IV value is not matching to that in the bin file.
Also, is it fine if i just send this "iv" to AES.new ? as below code?
decryptor = AES.new(key, AES.MODE_CBC, iv)
Also, if i have to send a hard coded IV value to AES new function, in what format i need to send it? i have a 16 bytes HEX value and i need to convert it into a byte string right?
Please let me know how to do it.

First question
Yes, that seems to be the proper method to read the IV. Make sure you opened the file in binary mode though, not in text mode.
Second question
Yes, if the IV is a 16 byte binary value that would be correct.
Third question
Using a constant IV would defeat the purpose of the IV altogether. But if you must use one that is specified as hexadecimals you should unhexlify it.

Related

Cryptopp: Get the padded string of input to the cipher

I am currently struggling around with the crypto++ lib for c++. All I want is to get the padded input to the cipher. I have the following snippet to encrypt a string "plain":
CryptoPP::StringSource(plain, true, new CryptoPP::StreamTransformationFilter(e, new CryptoPP::StringSink(cipher), CryptoPP::BlockPaddingSchemeDef::DEFAULT_PADDING));
where e is a cipher as:
CryptoPP::CBC_Mode<CryptoPP::SPECK128 >::Encryption e;
I can output the cipher text with the following snippet:
CryptoPP::StringSource(cipher, true, new CryptoPP::HexEncoder(new CryptoPP::FileSink(std::cout)));
What I need is to get the padded version of the string "plain". Is there anybody who can give me a hint to use the StreamTransformationFilter to get the output of the padded input string?
Just use CryptoPP::BlockPaddingSchemeDef::NO_PADDING instead of removing BlockPaddingSchemeDef altogether during decryption. It will then not expect padding and interpret the padding as plaintext.
The padding is always within the final 16 bytes (presuming a block size of 128 bits), starting at the right. Beware that the returned bytes are usually not characters as they are below < 0x20, which means that they are usually interpreted as control characters.

What is the default IV when encrypting with aes_256_cbc cipher?

I've generated a random 256 bit symmetric key, in a file, to use for encrypting some data using the OpenSSL command line which I need to decrypt later programmatically using the OpenSSL library. I'm not having success, and I think the problem might be in the initialization vector I'm using (or not using).
I encrypt the data using this command:
/usr/bin/openssl enc -aes-256-cbc -salt -in input_filename -out output_filename -pass file:keyfile
I'm using the following call to initialize the decrypting of the data:
EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, keyfile.data(), nullptr))
keyfile is a vector<unsigned char> that holds the 32 bytes of the key. My question is regarding that last parameter. It's supposed to be an initialization vector to the cipher algorithm. I didn't specify an IV when encrypting, so some default must have been used.
Does passing nullptr for that parameter mean "use the default"? Is the default null, and nothing is added to the first cipher block?
I should mention that I'm able to decrypt from the command line without supplying an IV.
What is the default IV when encrypting with EVP_aes_256_cbc() [sic] cipher...
Does passing nullptr for that parameter mean "use the default"? Is the default null, and nothing is added to the first cipher block?
There is none. You have to supply it. For completeness, the IV should be non-predictable.
Non-Predictable is slightly different than both Unique and Random. For example, SSLv3 used to use the last block of ciphertext for the next block's IV. It was Unique, but it was neither Random nor Non-Predictable, and it made SSLv3 vulnerable to chosen plaintext attacks.
Other libraries do clever things like provide a null vector (a string of 0's). Their attackers thank them for it. Also see Why is using a Non-Random IV with CBC Mode a vulnerability? on Stack Overflow and Is AES in CBC mode secure if a known and/or fixed IV is used? on Crypto.SE.
/usr/bin/openssl enc -aes-256-cbc...
I should mention that I'm able to decrypt from the command line without supplying an IV.
OpenSSL uses an internal mashup/key derivation function which takes the password, and derives a key and iv. Its called EVP_BytesToKey, and you can read about it in the man pages. The man pages also say:
If the total key and IV length is less than the digest length and MD5 is used then the derivation algorithm is compatible with PKCS#5 v1.5 otherwise a non standard extension is used to derive the extra data.
There are plenty of examples of EVP_BytesToKey once you know what to look for. Openssl password to key is one in C. How to decrypt file in Java encrypted with openssl command using AES in one in Java.
EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, keyfile.data(), nullptr))
I didn't specify an IV when encrypting, so some default must have been used.
Check your return values. A call should have failed somewhere along the path. Maybe not at EVP_DecryptInit_ex, but surely before EVP_DecryptFinal.
If its not failing, then please file a bug report.
EVP_DecryptInit_ex is an interface to the AES decryption primitive. That is just one piece of what you need to decrypt the OpenSSL encryption format. The OpenSSL encryption format is not well documented, but you can work it backwards from the code and some of the docs. The key and IV computation is explained in the EVP_BytesToKey documentation:
The key and IV is derived by concatenating D_1, D_2, etc until enough
data is available for the key and IV. D_i is defined as:
D_i = HASH^count(D_(i-1) || data || salt)
where || denotes concatentaion, D_0 is empty, HASH is the digest
algorithm in use, HASH^1(data) is simply HASH(data), HASH^2(data) is
HASH(HASH(data)) and so on.
The initial bytes are used for the key and the subsequent bytes for the
IV.
"HASH" here is MD5. In practice, this means you compute hashes like this:
Hash0 = ''
Hash1 = MD5(Hash0 + Password + Salt)
Hash2 = MD5(Hash1 + Password + Salt)
Hash3 = MD5(Hash2 + Password + Salt)
...
Then you pull of the bytes you need for the key, and then pull the bytes you need for the IV. For AES-128 that means Hash1 is the key and Hash2 is the IV. For AES-256, the key is Hash1+Hash2 (concatenated, not added) and Hash3 is the IV.
You need to strip off the leading Salted___ header, then use the salt to compute the key and IV. Then you'll have the pieces to feed into EVP_DecryptInit_ex.
Since you're doing this in C++, though, you can probably just dig through the enc code and reuse it (after verifying its license is compatible with your use).
Note that the OpenSSL IV is randomly generated, since it's the output of a hashing process involving a random salt. The security of the first block doesn't depend on the IV being random per se; it just requires that a particular IV+Key pair never be repeated. The OpenSSL process ensures that as long as the random salt is never repeated.
It is possible that using MD5 this way entangles the key and IV in a way that leaks information, but I've never seen an analysis that claims that. If you have to use the OpenSSL format, I wouldn't have any hesitations over its IV generation. The big problems with the OpenSSL format is that it's fast to brute force (4 rounds of MD5 is not enough stretching) and it lacks any authentication.

Saving key and iv to file AES implementation Crypto++

So I am using the Crypto++ Library to encrypt a file. I need to save the key and iv for future use. I am following this tutorial. Here is my function :
void AESUtil::encrypt(string filename,bool savekeys,string savefilename){
AutoSeededRandomPool rnd;
// Generate a random key
byte key[AES::DEFAULT_KEYLENGTH];
rnd.GenerateBlock(key, AES::DEFAULT_KEYLENGTH);
// Generate a random IV
byte iv[AES::BLOCKSIZE];
rnd.GenerateBlock(iv, AES::BLOCKSIZE);
Binary b;
string plaintext = b.decoder(filename);
unsigned char *ciphertext= new unsigned char[plaintext.size()+1];
ciphertext[plaintext.size()]='\0';
if(savekeys){
ofstream("key.bin", ios::binary).write((char*)key, sizeof(key));
}
CFB_Mode<AES>::Encryption cfbEncryption(key, AES::DEFAULT_KEYLENGTH, iv);
cfbEncryption.ProcessData(ciphertext,reinterpret_cast<const unsigned char*>(plaintext.c_str()),plaintext.size()+1);
ofstream outfile(savefilename.c_str());
outfile.write((char*)ciphertext,sizeof(ciphertext));
}
The files contain data in �/���� format. I want to know the best method to save the key and iv programmatically which are a byte array to a file and the ciphertext which is a unsigned char* to a separate file.
The key could be saved in a separate file. Normally the key is established between sender / receiver in advance, or it is encrypted using a public key of the receiver. Note that it doesn't make sense to save the key next to the ciphertext, as it would provide no protection whatsoever. The handling of keys is called key management and entire books have been written about it.
The IV is a different animal. The IV should be randomly generated. For CFB it should at least be unique and identical at both sides. Usually the IV is simply prefixed to the ciphertext, it doesn't have to be kept secret.
Your key and iv variables are the key and IV used to encrypt the plain text.
You didn't fill either; you're actually using an array filled with 0 bytes as both the key and IV for your encryption.
The IV is public information. You don't need to hide it. Save it the way you want.
The KEY is what you must keep safe. To do that you may decide how much effort you want to put on it to hide it from the external factors.
I have some keys that I don't care to leave them as a "plain text" in the binary code. (NO SECURITY, but my mom can't figure out what to do, but a beginner in reverse engineer will laugh at it.)
Some keys I do a play with the bytes, like inverting parts, separating them, XOR with something. (Very unsafe, but better than nothing, a programmer with decent knowledge in reverse engineering will be able to spend some time and eventually break the security)
Some other cases I use 3rd party advanced obfuscation... If possible, depending on what you want, you may even replace your encryption engine with some "white-box" cryptography. Then you will have your keys very well protected. But this is usually hard/expensive. It doesn't seem to be your case. (Yes, even a very advanced assembly guru will not be happy to start reverse engineer this case.)
Another solution, if you don't need the key on your binary, is to give it to the system's password manager. On Windows, it's called "Data Protection API", and on Mac, it's called "Keychain". Take a look at these, and then you will understand why this is considered security. But it's because all the passwords here are encrypted with the "user password" so nothing is stored "on disk". A turned-off device in this scenario is considered very secure.

Exporting Plaintext AES 128 Key to buffer/file Windows Crypto API c++

I'm having a lot of difficulty understanding and implementing the Windows Crypto API to Import and Export Keys in c++.
Despite reading through the MSDN documentation many many times I can't seem to get it to work in the way I want.
Below is a snippet of code from what i'm working on.
if(CryptAcquireContext(&CryptoHandle,NULL,provPointer, PROV_RSA_AES, 0xF0000000))
{
HCRYPTKEY aesKey;
//We now have context on Enhanced AES
if(CryptGenKey(CryptoHandle,CALG_AES_128,CRYPT_EXPORTABLE,&aesKey))
{
DWORD dwBlobLen;
BYTE* pbKeyBlob;
CryptExportKey(aesKey,0,PLAINTEXTKEYBLOB,0,NULL,&dwBlobLen);
if(pbKeyBlob=new BYTE[dwBlobLen])
{
if(CryptExportKey(aesKey, NULL,PLAINTEXTKEYBLOB, 0,pbKeyBlob, &dwBlobLen))
{
//Blah Blah
}
}
}
}
*(Where provPointer is a pointer to the Enhanced crypto api string.
As you might be able to tell from the snippet i'm trying to export a AES 128 key to plaintext.
In the debugger it all executes fine (No visible errors) but I don't understand the outcome at all.
The first call to CryptExportKey fills the dwBlobLen with '28' (What does this mean? Why?)
After the second CryptExport key i've tried writing pbKeyBlob(Which I assume points to the key) to file But I just end up with a constant set of bytes (Same for every try) followed by a set of bytes that I different every time (I assume this is some of the key) (Which add to 28 bytes total)
I'd really appreciate if someone could identify where I've gone wrong. I'm pretty clueless with the whole crypto lingo (Sessions,machine keys, blobs etc.)
In the future I'd like to be able to generate an AES key, use it and export it into a file in a form where I can import it again later.
Thanks in advance.
I'm not an expert on the Windows Cryptography API (or on cryptography in general) but I believe I can shed some light on what's going on here.
The first call to CryptExportKey puts 28 in dwBlobLen because that is the size of the blob that it will created when the key is exported. This is in the MSDN docs: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379931%28v=vs.85%29.aspx
AS far as what you're doing wrong. You aren't doing anything wrong. You are asking CryptExportKey to export a plaintext blob which has the following layout:typedef struct _PLAINTEXTKEYBLOB {
BLOBHEADER hdr;
DWORD dwKeySize;
BYTE rgbKeyData[];
} PLAINTEXTKEYBLOB, *PPLAINTEXTKEYBLOB;
As you can see, the blob starts with a header and a key size (which is the constant set of bytes which you have reported, and should be 12 bytes long), followed by the key data (which is the data that changes every time, and should be 16 bytes long). Remember you are generating a 128 bit key (which is 16 bytes).
The BLOBHEADER has the following layout:typedef struct _BLOBHEADER {
BYTE bType;
BYTE bVersion;
WORD Reserved;
ALG_ID aiKeyAlg;
} BLOBHEADER;
By the way, from the doc on the CryptImportKey function, you can't import the PLAINTEXTBLOB directly, because the BYTE array that you pass to CryptImportKey does not include the keysize. You need to pass a buffer with the BLOBHEADER followed by the key data.

I get "Invalid utf 8 error" when checking string, but it seems correct when i use std::cout

I am writing some code that must read utf 8 encoded text files, and send them to OpenGL.
Also using a library which i downloaded from this site: http://utfcpp.sourceforge.net/
When i write down this i can show the right images on OpenGL window:
std::string somestring = "abcçdefgğh";
// Convert string to utf32 encoding..
// I also set local on program startup.
But when i read the utf8 encoded string from file:
The library warns me about that the string has not a valid utf encoding
I can't send the 'read from file' string to OpenGL. It crashes.
But i can still use std::cout for the string that i read from file (it looks right).
I use this code to read from file:
void something(){
std::ifstream ifs("words.xml");
std::string readd;
if(ifs.good()){
while(!ifs.eof()){
std::getline(ifs, readd);
// do something..
}
}
}
Now the question is:
If the string which is read from file is not correct, how does it look as expected when i check it with std::cout?
How can i get this issue solved?
Thanks in advance:)
The shell to which you write output is probably rather robust against characters it doesn't understand. It seems, not all of the used software is. It should, however, be relatively straight forward to verify if you byte sequence is a valid UTF-8 sequence: the UTF-8 encoding is relatively straight forward:
each code point starts with a byte representing the number of bytes to be read and the first couple of bytes:
if the high bit is 0, the code point consists of one byte represented by the 7 lower bits
otherwise the number of leading 1 bits represent the total number of bytes followed by a zero bit (obiously) and the remaining bits become the high bits of the code point
since 1 byte is already represented, bytes with the high bit set and the next bit not set are continuation bytes: the lower 6 bits are part of the representation of the code point
Based on these rules, there are two things which can go wrong and make the UTF-8 invalid:
a continuation byte is encountered at a point where a start byte is expected
there was a start byte indicating more continuation bytes then followed
I don't have code around which could indicate where things are going wrong but it should be fairly straight forward to write such code.