如何解密用cbc_encrypt加密的内容(Linux GCC)

时间:2015-07-02 15:08:50

标签: c gcc encryption des

我想根据我在perl中所做的事情在C中进行加密/解密程序。编译的perl程序是2MB,所以我想如果我用C编写它将是一个较小的可执行文件大小。

我的问题是,当我加密它时,我无法解密它。自从我上次使用C以来,这已经很久了,所以我忘记了很多东西。有人请赐教我这里做错了什么?感谢。

/*
    ============================================================================
    Name        : test-c.c
    Description : Testing Project
                  Trying to do a C version of this perl code:
                    my $cipher = Crypt::CBC->new( -key => $salt_key, -cipher => 'DES' -header => 'none');
                    my $enc_text = $cipher->encrypt_hex($text);
    Requires    : -lcrypt
    References  :
      Function: cbc_crypt (char *key, char *blocks, unsigned len, unsigned mode, char *ivec)
      GNU C Library: DES Encryption (http://www.gnu.org/software/libc/manual/html_node/DES-Encryption.html#DES-Encryption)
      cbc_crypt (http://unix.derkeiler.com/Newsgroups/comp.unix.programmer/2012-10/msg00023.html)
    ============================================================================
    */

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <rpc/des_crypt.h>

    int main(void) {
        char key[]     = "aBcDeFg1";
        char pass[]    = "mypass1234test";
        char encbuff[] = "87654321";
        char decbuff[] = "87645321";
        int buffsize;
        int result;

        des_setparity(key);

        /* Encrypt pass, result is in encbuff */
        buffsize = sizeof(pass);
        /* Add to pass to ensure size is divisable by 8. */
        while (buffsize % 8) {
            pass[buffsize++] = '\0';
        }

        printf("Encrypted: ");
        result = cbc_crypt(key, pass, buffsize, DES_ENCRYPT | DES_SW, encbuff);
        if (DES_FAILED(result) || strcmp(encbuff, "") == 0) {
            if(strcmp(encbuff, "") == 0) {
                printf("*** Null Output ***\n");
            } else {
                printf("*** Encryption Error ***\n");
            }
        } else {
            printf("%s\n", encbuff);
        }

        /* Decrypt encbuff, result is in decbuff */

        /* FIXME: Decryption doesn't work:
            Encrypted: ,�7&���8
            Decrypted: *** Decryption Error ***
        */
        buffsize = sizeof(encbuff);
        /* Add to pass to ensure size is divisable by 8. */
        while (buffsize % 8) {
            encbuff[buffsize++] = '\0';
        }

        printf("Decrypted: ");
        result = cbc_crypt(key, encbuff, buffsize, DES_DECRYPT | DES_SW, decbuff);
        if(DES_FAILED(result) || strcmp(decbuff, "") == 0) {
            if(strcmp(encbuff, "") == 0) {
                printf("*** Null Output ***\n");
            } else {
                printf("*** Decryption Error ***\n");
            }
        } else {
            printf("%s\n", decbuff);
        }

        return 0;
    }

1 个答案:

答案 0 :(得分:0)

正如@Brian_Sidebotham所注意到的,使用char str[10];buffsize=sizeof(str);...str[buffsize++]='\0'在c中并不是一件好事。超出数组末尾的写入可能会触发未定义的行为。它可能工作或提供错误的结果或由于分段错误而停止。所以要做的第一件事就是使用更大的缓冲区。例如:

char key[9];
sprintf(key,"12345678");

char password[420];
sprintf(password,"i am not going to write my password here.");

请注意,为\0自动添加以构建有效c字符串的空终止字符sprintf()留出一些位置是9而不是8。

此外,cbc_crypt()的最后一个参数不是输出。它不是加密的字符串,而是链接的8字节初始化向量。这样,如果您需要加密多个字符串,它会阻止明文中的规则出现在密文中。由于要对密文进行解密,因此必须提供相同的初始化向量。加密就地执行:输入字符串pass将被加密文本覆盖。

最后,请确保您的字符串足够大,因为加密文本似乎略大于明文。

以下代码可以使用。它由gcc main.c -o main

编译
/*
    ============================================================================
    Name        : test-c.c
    Description : Testing Project
                  Trying to do a C version of this perl code:
                    my $cipher = Crypt::CBC->new( -key => $salt_key, -cipher => 'DES' -header => 'none');
                    my $enc_text = $cipher->encrypt_hex($text);
    Requires    : -lcrypt
    References  :
      Function: cbc_crypt (char *key, char *blocks, unsigned len, unsigned mode, char *ivec)
      GNU C Library: DES Encryption (http://www.gnu.org/software/libc/manual/html_node/DES-Encryption.html#DES-Encryption)
      cbc_crypt (http://unix.derkeiler.com/Newsgroups/comp.unix.programmer/2012-10/msg00023.html)
    ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rpc/des_crypt.h>

#define BUFFSIZE 420
int main(void) {
    //  char key[]     = "aBcDeFg1";
    char key[9];
    sprintf(key,"aBcDeFg1");
    //char pass[]    = "mypass1234test";
    char pass[BUFFSIZE];
    sprintf(pass,"mypass1234test");

    //  char encbuff[] = "87654321";
    char ivec[9];
    sprintf(ivec,"87654321");
    //  char decbuff[] = "87645321";
    char ivectemp[9];
    strcpy(ivectemp,ivec);
    int buffsize;
    int result;

    des_setparity(key);

    /* Encrypt pass, result is in encbuff */
    buffsize = strlen(pass);
    printf("buffsize is %d\n",buffsize);
    /* Add to pass to ensure size is divisable by 8. */
    while (buffsize % 8 && buffsize<BUFFSIZE) {
        pass[buffsize++] = '\0';
    }
    printf("pass is %s\n",pass);
    printf("buffsize is %d\n",buffsize);
    printf("Encrypted: ");
    result = cbc_crypt(key, pass, buffsize, DES_ENCRYPT | DES_SW, ivectemp);
    if (DES_FAILED(result) || strcmp(pass, "") == 0) {
        if(strcmp(pass, "") == 0) {
            printf("*** Null Output ***\n");
        } else {
            printf("*** Encryption Error ***\n");
        }
    } else {
        printf("%s\n", pass);
    }

    /* Decrypt encbuff, result is in decbuff */

    /* FIXME: Decryption doesn't work:
            Encrypted: ,�7&���8
            Decrypted: *** Decryption Error ***
     */
    buffsize = strlen(pass);
    printf("buffsize is %d\n",buffsize);
    /* Add to pass to ensure size is divisable by 8. */
    while (buffsize % 8 && buffsize<BUFFSIZE) {
        pass[buffsize++] = '\0';
    }
    printf("buffsize is %d\n",buffsize);
    printf("Decrypted: ");
    //keeping the same initialization vector for decrypting, encrypt has altered ivectemp
    strcpy(ivectemp,ivec);
    result = cbc_crypt(key, pass, buffsize, DES_DECRYPT | DES_SW, ivectemp);
    if(DES_FAILED(result) || strcmp(pass, "") == 0) {
        if(strcmp(pass, "") == 0) {
            printf("*** Null Output ***\n");
        } else {
            printf("*** Decryption Error ***\n");
        }
    } else {
        printf("%s\n",pass);
    }

    return 0;
}

现在......关于安全的几句话......根据wikipedia page about the Data Encryption Standard NBS DES

  现在认为DES对许多应用程序来说都是不安全的。这主要是由于56位密钥大小太小; 1999年1月,distributed.net和Electronic Frontier Foundation合作在22小时15分钟内公开破解DES密钥

例如,您可以通过openssl库切换到AES的实现。例如,请参阅How to do encryption using AES in OpensslSimple AES encryption decryption with openssl library in CAES (aes-cbc-128, aes-cbc-192, aes-cbc-256) encryption/decryption with openssl C