Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无法使用openssl CLI解密消息,该CLI是使用openssl API加密的_C_Linux_Shell_Openssl - Fatal编程技术网

无法使用openssl CLI解密消息,该CLI是使用openssl API加密的

无法使用openssl CLI解密消息,该CLI是使用openssl API加密的,c,linux,shell,openssl,C,Linux,Shell,Openssl,我使用的是上面的代码 在这里稍微修改了代码 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/aes.h> #include <openssl/crypto.h> unsigned char aes_key[]={0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0x

我使用的是上面的代码

在这里稍微修改了代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/crypto.h>  

unsigned char aes_key[]={0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf};

/* Print Encrypted and Decrypted data packets */
void print_data(const char *tittle, const void* data, int len);

int main( )
{
    /* Input data to encrypt */
    unsigned char aes_input[]={0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf};

    fprintf(stderr,"%s\n",SSLeay_version(SSLEAY_VERSION));

    /* Init vector */
    //unsigned char iv[AES_BLOCK_SIZE];
    unsigned char iv[]={0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf};
    //memset(iv, 0x00, AES_BLOCK_SIZE);

    /* Buffers for Encryption and Decryption */
    unsigned char enc_out[sizeof(aes_input)];
    unsigned char dec_out[sizeof(aes_input)];

    /* AES-128 bit CBC Encryption */
    AES_KEY enc_key, dec_key;
    AES_set_encrypt_key(aes_key, sizeof(aes_key)*8, &enc_key);
    AES_cbc_encrypt(aes_input, enc_out, sizeof(aes_input), &enc_key, iv,         AES_ENCRYPT);

    FILE *fp = fopen("id_encrypted","w");
    fwrite(enc_out, sizeof(enc_out), 1, fp); // write all the new buffer
    fclose(fp);

    /* AES-128 bit CBC Decryption */
    //memset(iv, 0x00, AES_BLOCK_SIZE); // don't forget to set iv vector again, else you can't decrypt data properly
    //unsigned char iv[AES_BLOCK_SIZE];
    unsigned char iv2[]={0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf};
    AES_set_decrypt_key(aes_key, sizeof(aes_key)*8, &dec_key); // Size of key is in bits
    AES_cbc_encrypt(enc_out, dec_out, sizeof(aes_input), &dec_key, iv2, AES_DECRYPT);

    /* Printing and Verifying */    
    print_data("\n Original ",aes_input, sizeof(aes_input)); // you can not print data as a string, because after Encryption its not ASCII

    print_data("\n Encrypted",enc_out, sizeof(enc_out));

    print_data("\n Decrypted",dec_out, sizeof(dec_out));

    return 0;
}

void print_data(const char *tittle, const void* data, int len)
{
    printf("%s : ",tittle);
    const unsigned char * p = (const unsigned char*)data;
    int i = 0;

    for (; i<len; ++i)
        printf("%02X ", *p++);

    printf("\n");
}
但是,下面的错误消息和输出文件是空的

bufsize=8192
hex string is too short, padding with zero bytes to length
hex string is too short, padding with zero bytes to length
bad decrypt
139861660053952:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:../crypto/evp/evp_enc.c:537:

有人能帮我解释为什么它不起作用吗?我想,问题在于我使用的openssl命令,因为我们可以看到代码对加密和解密都有效。

不要以这种方式编写加密代码。您正在使用低级别的AES API,该API专为了解他们所做工作的高级用户而设计。特别是,他们没有:

  • 执行填充-这在大多数情况下都是必需的(在OpenSSL CLI解密期间也是需要的)
  • 默认情况下,使用优化和固定时间(即最安全的)实现
它们也很容易被误用,射中自己的脚。出于上述原因,OpenSSL项目团队长期以来不鼓励使用低级别AES API,并将在下一版本的OpenSSL中弃用:

相反,您应该使用EVP API。有关示例代码,请参见本页:

除此之外,在OpenSSL CLI上指定密钥和iv的方式上还有一些其他问题。“-K”参数需要十六进制的键。每个十六进制数字代表4位(不是8位)。因此,您给出的密钥相当于:

01 23 45 67 89 ab cd ef
但你想要的是:

00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
静脉注射也有类似的问题。所以你真正想要的是:

$openssl enc-d-v-aes-128-cbc-输入id加密-输出id解密-K“000102030405060708090a0b0c0d0e0f”-iv“0001020304050608090A0C0D0F”
但是,在您修复加密代码以进行适当的填充之前,这仍然不起作用

编辑以添加:


您还可以使用
-nopad
选项进行无填充的解密。然而,这仍然是最好的重写您的代码不需要这样做。

不要这样写您的加密代码。您正在使用低级别的AES API,该API专为了解他们所做工作的高级用户而设计。特别是,他们没有:

  • 执行填充-这在大多数情况下都是必需的(在OpenSSL CLI解密期间也是需要的)
  • 默认情况下,使用优化和固定时间(即最安全的)实现
它们也很容易被误用,射中自己的脚。出于上述原因,OpenSSL项目团队长期以来不鼓励使用低级别AES API,并将在下一版本的OpenSSL中弃用:

相反,您应该使用EVP API。有关示例代码,请参见本页:

除此之外,在OpenSSL CLI上指定密钥和iv的方式上还有一些其他问题。“-K”参数需要十六进制的键。每个十六进制数字代表4位(不是8位)。因此,您给出的密钥相当于:

01 23 45 67 89 ab cd ef
但你想要的是:

00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
静脉注射也有类似的问题。所以你真正想要的是:

$openssl enc-d-v-aes-128-cbc-输入id加密-输出id解密-K“000102030405060708090a0b0c0d0e0f”-iv“0001020304050608090A0C0D0F”
但是,在您修复加密代码以进行适当的填充之前,这仍然不起作用

编辑以添加:


您还可以使用
-nopad
选项进行无填充的解密。然而,这仍然是最好的重写您的代码,不需要这样做。

“0123456789abcdef”
0x00,0x01,0x02…不同。
注意:在某些系统上(咳嗽窗口咳嗽),您必须
fopen
使用模式
“wb”
(和
“rb”
阅读)正确处理加密数据或二进制数据。此外,您的明文和密文都不是C字符串。
“0123456789abcdef”
0x00、0x01、0x02…不同。
注意:在某些系统(cough Windows cough)上,您必须
fopen
以模式
“wb”
(和
“rb”
读取)正确处理加密或其他二进制数据。此外,您的明文不是C字符串,也不是密文。。。。或者他们添加了
-nopad
。使用不带填充的块模式灵活性要低得多,通常不受欢迎,但即使在
EVP{Cipher/Encrypt/Decrypt}*
中也支持它,谢谢@dave_thompson_085,这是正确的。我已经在我的答案中添加了这些信息。谢谢@Matt Caswell@dave\u thompson\u 085。使用
-nopad
有效。但请注意,基于此[,我必须使用输入作为AES_块大小的倍数。使用输入作为
AES_输入[]=“0123456789abcde”;
openssl enc-d-AES-128-cbc-输入id加密-输出id解密-K“000102030405060708090A0C0D0F”-iv“000102030405060708090A090A0B0C0D0F”-nopad
也可以正常工作。因此使用EVP*更好,因为它不必处理所有这些问题……或者它们添加了
-nopad
。使用块模式而不填充灵活性要低得多,而且通常不受欢迎,但即使在
EVP{Cipher/Encrypt/Decrypt}中也支持它*
谢谢@dave_thompson_085,这是正确的。我已将该信息添加到我的答案中。谢谢@Matt Caswell@dave_thompson_085。使用
-nopad
有效。但请注意,基于此[,我必须将输入用作AES_块大小的倍数。将输入用作
AES_输入[]=“0123456789abcde”
openssl enc-d-aes-128-cbc-in-id\u加密-out-id\u解密-K“000102030405060708090a0b0c0d0e0f”-iv“000102030405060708090A0C0D0E0F”-nopad
也可以正常工作。因此使用EVP*更好,因为不必处理所有这些问题。