在openssl到DES_ncbc_encrypt的API中的等效命令是什么?

时间:2017-05-23 04:19:29

标签: c++ openssl

假设我在shell中有这个命令

PermissionRule

和c ++代码

> echo -n "abc" | openssl enc -e -K 4a08805813ad4689 -iv 1112131415161718 -des-cbc -a -p -v
salt=E0BE670000000000
key=4A08805813AD4689
iv =1112131415161718
lb5mBZNE/nU=
bytes read   :       3
bytes written:      13

> echo -n "abc" | openssl enc -e -K 4a08805813ad4689 -iv fadced8beb69425b -des-cbc -a -p -v
salt=E0BE670000000000
key=4A08805813AD4689
iv =FADCED8BEB69425B
XXlljYbfJYg=
bytes read   :       3
bytes written:      13

然后我构建并运行它

#include <string.h>

#include <iostream>
#include <string>

#include <openssl/bio.h>
#include <openssl/des.h>
#include <openssl/evp.h>

int b64encode(char* in, int in_len, char* out, int out_cap_len);
int b64decode(char* in, int in_len, char* out, int out_cap_len);
int b64code(char* in, int in_len, char* out, int out_cap_len, bool way);

int b64encode(char* in, int in_len, char* out, int out_cap_len)
{
    return b64code(in, in_len, out, out_cap_len, true);
}

int b64decode(char* in, int in_len, char* out, int out_cap_len)
{
    return b64code(in, in_len, out, out_cap_len, false);
}

int b64code(char* in, int in_len, char* out, int out_cap_len, bool way)
{
    BIO* b64 = BIO_new(BIO_f_base64());
    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
    BIO* bio = BIO_new(BIO_s_mem());
    BIO_push(b64, bio);
    int out_len = 0;
    if (way)
    {
        BIO_write(b64, in, in_len);
        BIO_flush(b64);
        out_len = BIO_read(bio, out, out_cap_len);
    }
    else
    {
        BIO_write(bio, in, in_len);
        BIO_flush(bio);
        out_len = BIO_read(b64, out, out_cap_len);
    }
    BIO_free_all(b64);
    return out_len;
}

void hexdump(unsigned char* ptr, int len)
{
    for (int i = 0; i < len; ++i)
    {
        printf("%02x", *(ptr + i));
    }
    printf("\n");
    return;
}

int main(int argc, char* argv[])
{
    std::string text("abc");
    unsigned char cipher[1024] = "";
    DES_key_schedule schedule;
    DES_cblock key = { 0x4a, 0x08, 0x80, 0x58, 0x13, 0xad, 0x46, 0x89 };
    DES_cblock ivec = { 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18 };
    DES_set_key_checked(&key, &schedule);
    printf("initialized:\n");
    printf("key=");
    hexdump(key, sizeof key);
    printf("iv =");
    hexdump(ivec, sizeof ivec);
    DES_ncbc_encrypt((unsigned char*)text.c_str(), cipher, (long)text.length(), &schedule, &ivec, DES_ENCRYPT);
    printf("updated:\n");
    printf("key=");
    hexdump(key, sizeof key);
    printf("iv =");
    hexdump(ivec, sizeof ivec);
    char b64encoded[1024] = "";
    b64encode((char*)cipher, strlen((char*)cipher), b64encoded, sizeof b64encoded - 1);
    std::cout << b64encoded << std::endl;
    return 0;
}

因此,如果我想使用> g++ -o zdex.bex zdes.cpp -lcrypto && ./zdex.bex initialized: key=4a08805813ad4689 iv =1112131415161718 updated: key=4a08805813ad4689 iv =fadced8beb69425b +tzti+tpQls= 实用程序获取相同的结果+tzti+tpQls=,如何更改使用它的方式,是否需要更改openssl或{{1}的字节顺序或者也许是我不知道的密码名称。提前谢谢。

1 个答案:

答案 0 :(得分:0)

我明白了。

由于openssl实用程序需要多个块长度输入数据,因此无法执行此操作。

在调用DES_ncbc_encrypt("abc", ...)的c ++代码中,输入明文为"abc",但是传递&#34; abc&#34;到openssl实用程序输入明文与附加的填充为"abc\x05\x05\x05\x05\x05",这意味着它调用DES_ncbc_encrypt("abc\x05\x05\x05\x05\x05", ...),这只是因为openssl实用程序使用了信封模式调用DES_ncbc_encrypt函数而不是直接调用DES_ncbc_encrypt EVP_ *模式执行填充工作。

但是如果输入clear-text已经多个块长度,您可以使用-nopad实用程序命令中的openssl来禁用EVP自动填充程序,只有这样,我们才能得到相同的结果。