Encrypting text file with AES-256 CBC - c++

I've been trying to pick up C++ and computer security in my own free time and I've been attempting some CTF challenges.
The challenge was about finding out the number of words (N) in a text file (x.txt), and using N as a key to encrypt the text file (x.txt) using AES-256 CBC and outputting a new text file (y.txt) with the encrypted contents.
I have no problems getting the number of words from the text file, but I was just wondering if anyone knows how to perform the encryption stated?
I've been reading up on OpenSSL for this but I can't proceed further. I assume the IV would be zero in this case?
Thanks in advance.

I assume the IV would be zero in this case?
An IV or Initialization Vector, is the "seed" for encryption. It is needed so that plaintexts that are similar don't look similar when encrypted. It is meant to never repeat between different encryption runs and is not secret. A zero IV (or any other fixed IV) would thus defeat the purpose.
A typical approach with AES-CBC is during encryption to generate a random IV and store it together with the ciphertext. Then during decryption read it in and use it to initialize the decryptor.
To know more about the OpenSSL API's to use, refer to OpenSSL Wiki - Symmetric Encryption.

I'm currently learning about AES too. Here are some resources I found useful:
How to perform AES encryption:
It boils down to 4 steps per round:
Substitute bytes (using the S-box)
Shifting the rows
Mixing the columns
Adding the round key
There's a really good video about how to perform each AES round by Professor Paar. Here is a link to his AES video. His whole channel is really a gold mine with regards to learning crypto. Note: You will need to hard code the S-box or include it somehow.
One thing Prof. Paar doesn't explain in the video is key expansion (aka how to get each round key). You can find a java implementation of key expansion on Professor Wagner's page here. It should be relatively straight forward to refactor into C++. Just remember to include the round constant table.

Related

Creating IV for CNG encryption

I'm trying to rework the CNG encryption example in the Microsoft documentation. One peculiar thing about the example is that the encryption IV is hard coded.
I don't know a lot about encryption but my understanding is that it is more secure to generate a random IV for each encrypted data.
Does anyone have any links or examples for how I'd create a good IV for encryption?
Is it enough to just use rand() to come up with N random byte values?

(C++) Decrypting a custom Polybius square

I'm working on a project related to a cryptography systems, and I need some help. Here's the related code: Link
This is just a main part related to encryption. My goal is to make encryption and decryption. But I'm stuck with the decryption.
My only idea was to decrypt it through the switch-case construction, but it's kinda stupid, right?
So, do you have any ideas what do I need to add to make it decryptable without much CPU and RAM usage?
Thanks in advance!
P.S. This is my first question here, so if I've made something wrong - sorry)
The hardcoded way, using a dictionary (map) or hash table (unordered_map) works. In cryptography it is not uncommon to hardcode tables of data.
You already hardcoded an array for encryption. If you use a hash table or dictionary, that can work both for encryption and decryption, requiring a single one.

Parse encrypted file with openssl

I have encrypted a file with openssl, now I would like to read the encrypted file (actually parse that file) without decrypting it. Basically I want to see if the encrypted file contains a certain word. How can I do that? I searched different blogs and posts and the only solution I could come up with is to decrypt the file (which creates a new READABLE file), search the word in the decrypted file and then remove it. Since I don't like having to create a decrypted copy of the file and then remove it, is there any way that I can parse/read the file without decrypting it? I should probably mention that I am using c++, but I don't think it really matters, am I correct?
Thanks in advance for all the help you can give me.
There is no way to parse a file that is encrypted (at least if you are using a reasonable, not trivially breakable - pretty much everything beyond a Ceasar cipher or a XOR cipher counts as "not trivially breakable" in this context).
In other words, you will need to find a way to decrypt the content - one solution is of course to decrypt to memory, or to stdout and use a pipe to read from the file.
An example (written here as a general idea, the exact code may need some adjusting):
FILE* p = popen("openssl des3 -d -in myfile.encrypted", "r");
int ch;
while((ch = fgetc(p)) != EOF)
{
... process a character at a time ...
}
pclose(p);
I have encrypted a file with openssl, now I would like to read the encrypted file (actually parse that file) without decrypting it... to see if the encrypted file contains a certain word.
To preserve semantic security, you need to use a homomorphic encryption scheme. OpenSSL does not support those cryptosystems, so its probably not possible using OpenSSL.
If you don't care about semantic security, then you can probably use any number of schemes. Mats gave you a couple of them. But they will leak information like a sieve and are probably trivial to break with simple techniques like frequency analysis.
You might want to read up on Fully Homomorphic Encryption and Somewhat Homomorphic Encryption schemes. If the scheme is built on a lattice, then the NTRU library might offer the scheme or a useful primitive. Shoup's NTL library might also offer the scheme or primitives. (I don't know because I don't use FHE or SHE schemes).
You should also talk to the folks on security.stackexchange.com or crypto.stackexchange.com.

What method/algorithm/library can securely encrypt then decrypt

The following project is done in C++ with WinAPI, for encryption/encoding I am using CryptoC++ but I am open to better libraries. I need to encrypt/encode email data, transmit it, then decrypt it at the other end so privileged users can read the email.
My original idea was just to encrypt the email text using SHA256 using my key(eg "MYKEY"). But I think I don't fully understand what hashing is. I understand that a string encrypted with SHA256 or MD5 or AES is impossible to decrypt, BUT I thought that if I encrypt the string with my special key("MYKEY") that I could then decrypt it aslong as I know the special key. Is that correct?
If not can you suggest a library, algorithm or method I can use to achieve my task of encrypting/encoding email text & ONLY being able to decrypt it if I have a key or some shared secret that will allow me to decrypt the data?
As said by Captain Giraffe, a hash algorithm is not an encryption algorithm (though they are both counted in the area of symmetric cryptography). A good hash function has no way to recover a message which fits to the produced hash (other than trying all possible messages to see if they give the same hash). (And also, a hash function has fixed size output, but has a variable size input, which means that there are many messages giving the same hash. It still should be difficult finding even one pair of messages giving the same hash, or a message for a given hash.)
You need an encryption algorithm. Most probably asymmetric encryption (using public keys to encrypt, private keys to decrypt) is a good idea.
Don't invent new cryptographic data formats or protocols. You will make mistakes, which make your product insecure.
For email encryption, use either OpenPGP (RFC 4880) or S/MIME (RFC 3851), or some subsets of one of these.
You can then use any library which supports the necessary algorithms, or some library which supports specifically these file formats.
SHA256 and MD5 are One way functions. i.e. There is no decryption. See Hashing http://en.wikipedia.org/wiki/Cryptographic_hash_function.
But you really need to read up on encryption procedures before attempting to create a secure communication.
That being said wikipedia has an article dedicated to implementations http://en.wikipedia.org/wiki/AES_implementations

How to prevent a file from being tampered with

I want to store confidential data in a digitally signed file, so that I know when its contents have been tampered with.
My initial thought is that the data will be stored in NVPs (name value pairs), with some kind of CRC or other checksum to verify the contents.
I am thinking of implementing the creating (i.e. writing) and verification (reading) of such a file, using ANSI C++.
Assuming this is the data I want to store:
//Unencrypted, raw data to be stored in file
struct PrivateInfo {
double age; weight;
FitnessScale fitness;
Location loc;
OtherStuff stuff;
};
//128-bit Encrypted Data (Payload to be stored in file)
struct EncryptedData {
// unknown fields/format ??
};
[After I have read a few responses to this question]
Judging by the comments I have received so far, I fear people are getting side tracked by the word "licensing" which seems to be a red flag to most people. I suspected that may be the case, but in todays atmosphere of heightened security and general nervousness, I thought I'd better detail what I needed to be "hiding" lest someone thought I was thinking of passing on the "Nuke password" to some terrorists or something. I will now remove the word "license" from my question.
View it more as a technical question. Imagine I am a student (which I am), and that I am trying to find out about recommended (or best practices) for encoding information that needs to be secure.
Mindful of the above, I will reformat my questions thus:
Given a struct of different data type fields, what is the "recommended" algorithm to give it a "reasonable secure" encryption (I still prefer to use 128 bit - but thats just me)
What is a recommended way of providing a ROBUST check on the encrypted data, so I can use that check value to know if the contents of the file (the Payload of encrypted data) differs from the original.?
First, note that "signing" data (to notice when it has been tampered with) is a completely separate and independent operation from "encrypting" data (to prevent other people from reading it).
That said, the OpenPGP standard does both. GnuPG is a popular implementation: http://www.gnupg.org/gph/en/manual.html
Basically you need to:
Generate a keypair, but don't bother publishing the public part.
Sign and encrypt your data (this is a single operation in gpg)
... storage ...
Decrypt and check the signature (this is also a single operation).
But, beware that this is only any use if you can store your private key more securely than you store the rest of the data. If you can't guarantee the security of the key, then GPG can't help you against a malicious attempt to read or tamper with your data. And neither can any other encryption/signing scheme.
Forgetting encryption, you might think that you can sign the data on some secure server using the private key, then validate it on some user's machine using the public key. This is fine as far as it goes, but if the user is malicious and clever, then they can invent new data, sign it using their own private key, and modify your code to replace your public key with theirs. Their data will then validate. So you still need the storage of the public key to be tamper-proof, according to your threat-model.
You can implement an equivalent yourself, something along the lines of:
Choose a longish string of random characters. This is your key.
Concatenate your data with the key. Hash this with a secure hash function (SHA-256). Then concatenate the resulting hash with your data, and encrypt it using the key and a secure symmetric cipher (AES).
... storage ...
Decrypt the data, chop off the hash value, put back the key, hash it, and compare the result to the hash value to verify that it has not been modified.
This will likely be faster and use less code in total than gpg: for starters, PGP is public key cryptography, and that's more than you require here. But rolling your own means you have to do some work, and write some of the code, and check that the protocol I've just described doesn't have some stupid error in it. For example, it has potential weaknesses if the data is not of fixed length, which HMAC solves.
Good security avoids doing work that some other, smarter person has done for you. This is the virtuous kind of laziness.
Err, why not use a well known encryption system like GPG?
The answers to the edited question depend on the specific scenario.
For q1 (encryption): if you encrypt and decrypt at your servers you can use a symmetric key algorithm. Otherwise you may want to use public key cryptography.
For q2, if you simply want to check if a file has changed you can use any cryptographic hash such as SHA-1 -- assuming that you can make sure that the hash itself wasn't change.
If the data generator and the verifier are both secure you can use MAC algorithm such as HMAC to to verify that the data and the MAC match. But this works only if the secret key remains secret.
Otherwise, you may be able to use digital signatures.
I'm going to change the phrasing of the question and see if it makes people happier (or I get downvoted). There are really two types of questions being asked:
You are making some computer game and you want to know if someone has been messing with your save files. (data signing)
You are writing a messaging program and want to keep people's message logs private. (data encryption)
I will deal with the second one (data encryption). It's a massively difficult topic and you should be looking for pre-built programs (such as PGP/GPG) even then it's going to take you a lot of time to understand and use properly. Think about encryption like this: it will be broken; your job is to make it not worth the effort. In other words make the effort required to break it greater than the value of the information.
As for the first one, again it can be broken. But a checksum is a good idea. see Amnon's answer for some links on that.
Hope this points you in the right direction. I'm not an expert on either topics but I hope this gives you a starting point. (you might want to re-phrase the question and see if you get some better answers)