当前位置: 首页 > 知识库问答 >
问题:

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

诸葛令
2023-03-14

我想根据我在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个答案

夏俊人
2023-03-14

正如@Brian_Sidebotham所注意到的,使用<code>char str[10];buffsize=大小(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.");

请注意,它是9,而不是8,为空终止字符< code>\0留出了一些空间,该字符由< code>sprintf()自动添加以构建有效的c字符串。

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

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

以下代码应该可以正常工作。它由 gcc 主编纂.c -o 主

/*
    ============================================================================
    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;
}

现在…关于安全的几句话…根据维基百科上关于数据加密标准NBS DES的页面:

对于许多应用程序来说,DES现在被认为是不安全的。这主要是由于56位密钥尺寸太小;1999年1月,distributed.net和电子前沿基金会合作,在22小时15分钟内公开破解了一个DES密钥

例如,您可以通过openssl库切换到AES的实现。请参阅如何在Openssl中使用AES进行加密,或使用C中的Openssl库进行简单AES加密解密,或使用Openssl C进行AES(AES-bc-128、AES-cb-192、AES-bc-256)加密/解密。

 类似资料:
  • 问题内容: 我有一个奇怪的问题 我的解决方案基于将硬编码文件解密为字节[] 因此,我写了一个小的Cypher类来帮助进行加密/解密…它曾经用来模拟在某个地方进行硬编码的密钥,以及另一个在其他地方存储的预加密密钥。但这与atm无关。 加密过程如下: 检索硬编码的字节数组 用它来解密key2 使用key2解密数据 使用key1进一步解密数据 已解密数据 我将加密的数据存储为十六进制字符串,使用这两个函

  • 问题内容: 我正在使用ExtJS框架。我在 JavaScript中 有MD5函数来加密某些JSON。我的后端使用Java,所以我想知道如何使用 Java 解密MD5 Javascript加密? 这是我正在使用的MD5函数的JS等效项: 问题答案: MD5是 哈希 (即单向转换),因此您无法对其进行解密。您可以将已知哈希与从明文计算出的哈希进行比较,以验证输入的有效性。Java已经为此内置了库。我在

  • 问题内容: 我需要用openssl生成的和密钥替换从Unix到Java代码的加密和解密步骤 我生成密钥 我在Unix中使用键(我需要在Java中执行) 这是我的尝试 但它不起作用,PKCS8EncodedKeySpec / X509EncodedKeySpec不正确…但是我不知道该放什么 问题答案: 我认为您在读取PEM文件时遇到问题。JPA不直接支持PEM格式。您有两种选择,要么将它们转换为DE

  • 问题内容: 按照本教程,我将使用flexiprovider基于椭圆曲线的不对称算法进行加密/解密。稍作修改,我将出于个人目的将公共密钥和私有密钥转换为Base64(例如存储到数据库或文本文件中)。但是我的代码不是在android设备中运行的,而在Java设备中运行的是dekstop,不是Java中的android和dekstop版本,我认为这是一个很大的差异(只是为了清理我的问题信息)。好的,在我

  • 问题内容: 我编写的使用3DES在Java中对字符串进行编码的每种方法都无法解密回原始字符串。是否有人有一个简单的代码片段,可以对字符串进行编码,然后再将其解码回原始字符串? 我知道我在此代码中的某个地方犯了一个非常愚蠢的错误。到目前为止,这是我一直在努力的工作: 注意,我不是从crypto方法返回BASE64文本,也不是在解密方法中不是对base64进行未编码的,因为我试图查看我是否在BASE6

  • 我的代码如下: 有人来帮我吗