27

I want to write a small program in C/C++ which reads a small text file, and encrypts it, using a "internal" key. Then I also want to write another small program which can decrypt the encrypted file using internally the same key.

I looked at openSSL site and googled but found not simple example, has somebody ever tried to do this thing?

jww
  • 97,681
  • 90
  • 411
  • 885
  • A question with similar example http://stackoverflow.com/questions/3141860/aes-ctr-256-encryption-mode-of-operation-on-openssl – enthusiasticgeek May 14 '12 at 15:18
  • You should use `EVP_*` functions. The `EVP_*` functions use hardware, like AES-NI (if available). See [EVP Symmetric Encryption and Decryption](https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption) on the OpenSSL wiki. In fact, you should probably be using authenticated encryption because it provides *both* confidentiality and authenticity. See [EVP Authenticated Encryption and Decryption](https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption) on the OpenSSL wiki. – jww May 15 '15 at 20:41

3 Answers3

24

Ideally, you could use an existing tool like ccrypt, but here goes:

#include <openssl/aes.h>

/* ... */


{
  int bytes_read, bytes_written;
  unsigned char indata[AES_BLOCK_SIZE];
  unsigned char outdata[AES_BLOCK_SIZE];

  /* ckey and ivec are the two 128-bits keys necesary to
     en- and recrypt your data.  Note that ckey can be
     192 or 256 bits as well */
  unsigned char ckey[] =  "thiskeyisverybad";
  unsigned char ivec[] = "dontusethisinput";

  /* data structure that contains the key itself */
  AES_KEY key;

  /* set the encryption key */
  AES_set_encrypt_key(ckey, 128, &key);

  /* set where on the 128 bit encrypted block to begin encryption*/
  int num = 0;

  while (1) {
    bytes_read = fread(indata, 1, AES_BLOCK_SIZE, ifp);

    AES_cfb128_encrypt(indata, outdata, bytes_read, &key, ivec, &num,
           AES_ENCRYPT);

    bytes_written = fwrite(outdata, 1, bytes_read, ofp);
    if (bytes_read < AES_BLOCK_SIZE)
  break;
  }
}

Decryption is done by calling AES_cfb128_encrypt with AES_DECRYPT as the last parameter. Note that this code hasn't been given anything more than the most elementary of testing, and that you really should use proper 8-bits random data for ckey and ivec.

EDIT: It seems AES_cfb128_encrypt accepts data of arbitrary length, so you're not required to encrypt in blocks of AES_BLOCK_SIZE (16) bytes.

agiaLab
  • 1,855
  • 1
  • 12
  • 6
Michiel Buddingh
  • 5,783
  • 1
  • 21
  • 32
  • Some direction from aes help doc, saying that: Not all possible variations of key size and modes of operation are provided by this library. For this reason, and others, applications should use the higher level functions L etc., instead of calling the AES functions directly. – solotim Dec 17 '09 at 07:37
  • @Michiel Budding': I've used your code and need to initialize int num; to the ivec size for it to work correctly. – Macarse Apr 21 '10 at 22:44
  • The ifp and ofp FILE pointers have been omitted. They should be declared before the while loop with `FILE *ifp = fopen("input_file", "rb"); FILE *ofp = fopen("output_file", "wb");` – Mo Beigi Apr 07 '15 at 06:12
16

Previous answers have pointed you towards how to do what you asked for.

I'd like to add a word on why you probably shouldn't do this.

What you are talking about is called "symmetric encryption" (the same key is used for encrypting and decrypting, as opposed to asymmetric encryption where everything encrypted with one key can only be decrypted by a specific counterpart).

Disassembling an executable to determine a hardcoded key being used is next-to-trivial. That means, anyone who gets his/her hands on one of your executables, ever, can break the encryption of any message ever exchanged.

Unless the application you have in mind is very specific, this means your setup might "look" secure, but isn't. In these cases, it's usually better not to encrypt at all, so that no-one involved falls for that false sense of security...

It's very good you are looking to standard libraries to do the encryption (instead of implementing / creating an algorithm yourself), but the protocoll (how applications, keys, and messages are used and exchanged) is at least as important as the cipher itself. You might want to have your ideas tested by someone dealing in cryptography, to tell you the weaknesses. (I'm sure there's enough of that kind here at StackOverflow. ;-) )

DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • +1 for the good advice. But, unlike what you say, at least two answers suggested NOT to do symmetric encryption (Andrew Austin's and mine). – bortzmeyer Jun 18 '09 at 15:59
  • I admit I haven't followed the links to find out what they were about. ;-) – DevSolar Jun 18 '09 at 16:59
  • 2
    I have to dissent a little (and of course I would); we have no idea what the OP has in mind. If the encryption and decryption are done on different computers, an internal key is secure. If he just wants to play around with the SSL libraries, security is irrelevant. I'll give you +1 for the advice, but "you shouldn't do this" is a bit too strong a summary. – Michiel Buddingh Jun 18 '09 at 20:43
  • Now it's "probably". I had a gut feeling about the OP, but you're right, the statement was a bit strong. – DevSolar Jun 19 '09 at 05:01
  • There is nothing wrong with using symmetric encryption. The problem in his question is the key storage. For eg. if the program asks for a password & then uses that to generate the key for encryption, it becomes perfectly secure. While decrypting again, the program has to ask for the password. Using asymmetric encryption here makes no sense - this is not the use case for asymmetric encryption. – user93353 Nov 14 '12 at 09:17
  • 1
    @user93353: All fine and well, but the OP was talking about an "internal" key, which smells of "hardcoded". – DevSolar Nov 14 '12 at 09:37
  • @DevSolar i appreciate the good advice here - i have never done encryption/decryption but now after reading RSA, github keys suddenly make sense! – David T. Oct 23 '14 at 23:04
1

OpenSSL is specifically concerned with implementing SSL and TLS which are protocols for encrypting data over a network. Since you are just looking to encrypt a file, it is possible to use OpenSSL but not ideal.

Instead, I would use something like BeeCrypt or Crypto++® Library 5.6.0 which both provide examples for their use.

Andrew
  • 1,853
  • 1
  • 14
  • 15
  • 6
    OpenSSL has both memory and file `BIO`'s, which are an abstraction. The library is fine with memory buffers, file buffers, sockets, and other I/O objects. The cryptography portion of the library (`libcrypto.a`) can be used stand alone; and the SSL portion (`libssl.a`) is built on top of the cryptography. – jww Jul 04 '14 at 23:24