Creating IV for CNG encryption - c++

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?

Related

Encrypting text file with AES-256 CBC

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.

how do or what is the best way to generate AES key using openssl programmatically?

how do or what is the best way to generate AES key using openssl programmatically? Saw recommendations using RAND_bytes. I also come across this API — AES_set_encrypt_key(....). But the first parameter seems to be user’s encrypted key. So, I think you I need to generate an AES key first b4 calling this API.
Please advise

Asymmetric authenticated encryption

I want to protect my data from being changed or read by unauthorized people. Searching around I found that Authenticated Encryption(AE) is a solution.
I know I can do AE in Crypto++ using any of CCM, GCM, or EAX. But I noticed they're using the same key to encrypt and decrypt data. I don't want that, I'd rather use asymmetric keys to encrypt and decrypt my data.
If I sign data using an asymmetric algorithm and then encrypt it using a symmetric algorithm, I will achieve what I want (Which should be safe since it's AtE method, right?).
But before I do that, are there any crypto libraries that do what I want already?
I know I can do Authenticated Encryption ... using ... CCM, GCM, or EAX. But I noticed they're using the same key to encrypt and decrypt data. I don't want that, I'd rather use asymmetric keys to encrypt and decrypt my data.
All the schemes I am aware will use a symmetric cipher for the bulk data encryption. The symmetric cipher can be a block cipher or a stream cipher.
I've also seen a few incorrect applications of RSA, where RSA is operated in ECB mode. That is, the data is "chunked" or "blocked", and then RSA is applied to each block. The Handbook of Applied Cryptography specifically warns against this.
The best you are probably going to do is Elliptic Curve Integrated Encryption Scheme (ECIES) or Discrete Log Integrated Encryption System (DLIES). Both are available in Crypto++. Both use public key (asymmetric) cryptography.
ECIES and DLIES combine a Key Encapsulation Mechanism (KEM) with a Data Encapsulation Mechanism (DEM). The system independently derives a symmetric cipher key and a MAC key from a common secret. Data is first encrypted under a symmetric cipher, and then the cipher text is MAC'd under an authentication scheme. Finally, the common secret is encrypted under the public part of a public/private key pair. The output of the encryption function is the tuple {K,C,T}, where K is the encrypted common secret, C is the ciphertext, and T is the authentication tag.
There is some hand waiving around the "common secret" since its actually the result of applying a Key Agreement function and later digested with a KDF. It uses the static public key and an ephemeral key pair. The person performing the decrypt uses their public key to perform the other half of the key exchange to arrive at the "common secret".
The KEM and the DEM avoid padding, so padding oracles are not a concern. That's why a KDF is used to digest the large "common secret" under the KEM. Omitting padding vastly simplifies the security proofs of the system. Because of the security proofs, ECIES and DLIES are IND-CCA2, which is one of the strongest you can achieve.
If I sign data using an asymmetric algorithm and then encrypt it using a symmetric algorithm...
Here's some related reading... First is Hugo Krawczyk's The Order of Encryption and Authentication for Protecting Communications. Second is Don Davis' Defective Sign & Encrypt in S/MIME, PKCS#7, MOSS, PEM, PGP, and XML.
The relevance here is: Krawczyk's paper deals with symmetric key cryptography and the Encrypt-then-Authenticate style of authenticated encryption (and how to perform authenticated encryption). Davis' paper deals with asymmetric cryptography and the disconnect between signing and encryption (and how to repair it).
But before I do that, are there any crypto libraries that do what I want already?
Yes (but it depends on what you want to do). Crypto++ is the only one I am aware that provides ECIES, DLIES, and a collection of PSSRs.
Bouncy Castle is a close second because it provides ECIES, but not DLIES. I'm not sure how many PSSRs it provides.
Crypto++, Bouncy Castle, OpenSSL (and others) provide the PSSR. You should not have any trouble finding a lib with PSSR.
You could possibly consider an OpenPGP-based solution. This would provide you with the functionality you desire and would scale to support arbitrary data sizes, unlike a solution based purely on asymmetric encryption (with no transport key).
There are a few open source implementations out there. BouncyCastle offer one, but I'm not sure they have a C++ implementation.
GPGME (GnuPG Made Easy). It's a high level encryption library in C and is LGPL licensed.

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

I'm using Crypto++ for RSA encryption. My plain text exceeds FixedMaxPlaintextLength. What should I do?

Should I break the text into chunks?
Is RSA the wrong encryption scheme?
Wrong scheme. The standard technique for message encryption (for example, PGP and CMS) is to generate a random symmetric session key K for something like AES and encrypted the message with AES using key K. Then encrypt K with the public key of each recipient of the message.
Typically, the asymmetric RSA algorithm is used for key exchanges. If you are encrypting larger chunks of data, it might be better to use something like AES.