-2

I'm trying to use the glibc cbc_crypt function to encrypt strings in c the program should be as portable as function which is why I'm using this library

here's my code:

#define _GNU_SOURCE
#include <stdio.h>
#include <crypt.h>
#include <string.h>
#include <rpc/des_crypt.h>

int main(int argc, char *argv[]) {
    int blah=0;
    char plaintext[]="mypass1234test";
    char key[]="aBcDeFg1";
    char encbuff[] = "87654321";
    char decbuff[] = "87645321";
    des_setparity(key);
    int size=sizeof(plaintext);
    printf("plaintext is %s\n",plaintext);
    printf("original size is %d\n",size);
    while (size % 8 && size < 420)
        plaintext[size++]='\0';
    printf("new size is %d\n",size);
    if (argc>1) {
        if (strcmp("encrypt",argv[1])==0) {
            blah=cbc_crypt(key,plaintext,size,DES_ENCRYPT | DES_SW,encbuff);
            printf("ciphertext is %s\n",plaintext);
            size = sizeof(plaintext);
            printf("original size is %d\n",size);
            while (size % 8 && size < 420)
                plaintext[size++]='\0';
            printf("new size is %d\n",size);
            blah=cbc_crypt(key,plaintext,size,DES_DECRYPT | DES_SW,decbuff);
            printf("plaintext is %s\n",plaintext);
        }
    }
    return 0;
}

when I try to run this program I get the following:

./a.out encryption
plaintext is mypass1234test
original size is 15
new size is 16
ciphertext is 0ю�sBKX,�7&���8@  @
original size is 15
new size is 16
plaintext is myp`rs12��~�ϖ@ @

My goal is to encrypt files and decrypt files, I'm open to use other cryptographic functions but I need this program to be portable( I would rather not use openssl as I have machines running without that library)

tonysdg
  • 1,335
  • 11
  • 32
Adel Ahmed
  • 638
  • 7
  • 24
  • 2
    Strong recommendation: **do not** implement your onw crypto functions! You are very, very likely to exploit whatever you are encrypting. Use a well-accepted standard library instead. Also: do not use DES anymore, it is definitively unsafe. Even Tripple-DES is deprecated. Instead use AES. – too honest for this site Jul 13 '15 at 20:13
  • What libraries in Linux provide AES that are installed in most distributions? – Adel Ahmed Jul 13 '15 at 20:34
  • Are you relying that something is installed? You know Apt etc.? – deviantfan Jul 13 '15 at 21:41
  • yeah I can work with package managers, but this should work on machines that have minimal packages installed(gentoo machines mainly, some redhat machines as well) I cannot guarantee the presence of many packages I can guarantee the presence of gnutls I'll check if openssl is there – Adel Ahmed Jul 13 '15 at 21:50
  • If you have to use crypto without a library, then just find the most liberal license for a (secure, well used) crypto lib and statically link that code into your application. That's still zillion times better than to code your own. PS a -1 vote just to show to others that this code is 1) a request to debug and/or 2) a request for libraries. Don't feel too bad about it :) – Maarten Bodewes Jul 24 '15 at 10:31

2 Answers2

2

I haven't fully reviewed your code, but here are a few things that are wrong.

  • The length of the plaintext and the ciphertext must be a multiple of 8 bytes. The cbc_crypt function doesn't do padding for you. You're passing a 15-byte buffer; depending on how cbc_crypt works and on your platform and on how your compiler is feeling today, this may result in another variable being overwritten at some point.
  • The loop where you add null bytes at the end of the plaintext overflows the buffer. plaintext only has room for 15 bytes, but you're writing 16. Depending on your platform and on how your compiler is feeling today, this may result in another variable being overwritten at some point.
  • The loop where you add null bytes at the end of the ciphertext results in garbage when you decrypt it. That's normal: “regular” ciphertext gives you garbage upon decryption. (That's in addition to the problem that this loop is writing outside the bounds of the array.)
  • The IV for CBC should be uniformly random, not constant. This won't result in invalid decryption but is bad for security.

In any case, the mere fact that you're using DES is bad for security. DES is long obsolete. Use AES instead.

There's no standard cryptographic library, but there are libraries with a very liberal license and a small footprint. Pick one and link its code statically into your code.

One possibility is to use libtomcrypt. There are code samples in the manual. If you only want encryption, use AES in CBC or CTR mode with a random IV/counter. If you also want authentication (i.e. detect if someone modified the ciphertext), use AES in GCM or CCM mode (again, random IV).

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
0

If you would like portable cryptography, so portable that it has no external dependencies, then I think your best choice is tweetnacl (allowing users to use the api-compatible libsodium if they desire). To encrypt or decrypt a file see the crypto_secretbox() function.

Thomas M. DuBuisson
  • 64,245
  • 7
  • 109
  • 166