无法使用Cygwin和OpenSSL

时间:2016-02-19 11:36:00

标签: c debugging openssl cryptography cygwin

我想使用OpenSSL计算CMAC。我发现this question帮助了我。

但我遇到以下代码的问题:

#include <openssl/cmac.h>

void dispHex(const unsigned char *buffer, unsigned int size) {
    int i=0;

    for (i=0; i<size-1; i++) {
        printf("%02X ", buffer[i]);
    }
    printf("%02x\n", buffer[i]);
}

int main() {
    size_t out_len;
    unsigned char res[16];

    unsigned char mac_key[16] = { 0x00, 0x01 ,0x02 ,0x03, 0x04, 0x05, 0x06, 0x07,
                            0x00, 0x01 ,0x02 ,0x03, 0x04, 0x05, 0x06, 0x07};

    unsigned char msg[16] = { 0x00, 0x01 ,0x02 ,0x03, 0x04, 0x05, 0x06, 0x07,
                            0x00, 0x01 ,0x02 ,0x03, 0x04, 0x05, 0x06, 0x07};

    CMAC_CTX *cmac = CMAC_CTX_new();
    CMAC_Init(cmac, mac_key, 16, EVP_aes_128_cbc(), NULL);
    CMAC_Update(cmac, msg, sizeof(msg));
    CMAC_Final(cmac, res, &out_len);
    dispHex(res, sizeof(res));

    return 0;
}

我使用gcc -o test_cmac test_cmac_openssl.c -L C:/OpenSSL-Win32 -llibeay32 -I C:/OpenSSL-Win32/include进行编译,它会毫无问题地生成test_cmac.exe

但是当我运行它(./test_cmac.exe)时,没有任何反应。它只是打印一个空行并停止:

xxx@DESKTOP /cygdrive/e/
$ ./test_cmac.exe

xx@DESKTOP /cygdrive/e/

即使我在CMAC计算之前添加printf("...");,它也会采用相同的方式。

奇怪的是以下程序:

#include <openssl/hmac.h>

void dispHex(const unsigned char *buffer, unsigned int size) {
    int i=0;

    for (i=0; i<size-1; i++) {
        printf("%02X ", buffer[i]);
    }
    printf("%02X\n", buffer[i]);
}

int main() {
    size_t out_len;
    unsigned char res[32];

    unsigned char mac_key[16] = { 0x00, 0x01 ,0x02 ,0x03, 0x04, 0x05, 0x06, 0x07,
                            0x00, 0x01 ,0x02 ,0x03, 0x04, 0x05, 0x06, 0x07};

    unsigned char msg[16] = { 0x00, 0x01 ,0x02 ,0x03, 0x04, 0x05, 0x06, 0x07,
                            0x00, 0x01 ,0x02 ,0x03, 0x04, 0x05, 0x06, 0x07};

    HMAC_CTX hmac;
    HMAC_CTX_init(&hmac);
    HMAC_Init_ex(&hmac, mac_key, 16, EVP_sha256(), NULL);
    HMAC_Update(&hmac, msg, sizeof(msg));
    HMAC_Final(&hmac, res, &out_len);
    dispHex(res, sizeof(res));

    return 0;

}

正常运行:在gcc -o test_hmac test_hmac_openssl.c -L C:/OpenSSL-Win32 -llibeay32 -I C:/OpenSSL-Win32/include./test_hmac.exe之后我得到:

xxx@DESKTOP /cygdrive/e/
$ ./test_hmac.exe
...9A 21 F8 2D 60 84 6C 09 08 98 A5 1F 23 8C C8 8F C4 A9 0C C4 49 45 DA 10 B9 39 C0 93 C3 10 60 BE

xxx@DESKTOP /cygdrive/e/

所以我有点困惑...... 为什么它适用于HMAC原语而不适用于CMAC原语?有没有人遇到过这种问题?

我使用的是OpenSSL 32位版本:openssl version返回OpenSSL 1.0.2e 3 Dec 2015。 我还检查了在PATH环境变量中声明了C:\OpenSSL-Win32\

2 个答案:

答案 0 :(得分:2)

查看IMPL,似乎未执行CMAC对象的初始化,因为NULLint CMAC_Init(CMAC_CTX *ctx, const void *key, size_t const EVP_CIPHER *cipher, ENGINE *IMPL) if (!key && !cipher && !IMPL && keylen == 0) { /* Not initialised */ if (ctx->nlast_block == -1) return 0; if (!EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, NULL, zero_iv)) return 0; memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(ctx->cctx)); ctx->nlast_block = 0; return 1; }

myNameSpace = {

  STATICPROPERTY: 'test',

  method: function() {
    var variable = 'thisVarIsPrivateToMethod';
    this.variable = 'dynamic';
  },

  init: function() {
    this.method();

    console.log(this.STATICPROPERTY);  // will log "test"
    console.log(this.variable);        // will log "dynamic"
  }
}

myNameSpace.init(); 

答案 1 :(得分:1)

  

为什么它适用于HMAC原语而不适用于CMAC原语?有没有人遇到过这种问题?

我猜大多数问题都是由于混合和匹配编译器造成的。当您使用GCC时,Shining Light的Win32 OpenSSL使用Microsoft的编译器。可能还有一些混合和匹配的运行时。

我很惊讶HMAC代码在配置中按预期工作。我猜你很幸运。

以下对我有用,但存在一些差异:

#include <openssl/evp.h>
#include <openssl/cmac.h>

#include <stdio.h>
#include <string.h>
#include <assert.h>

void dispHex(const unsigned char *buffer, unsigned int size) {
    unsigned int i=0;

    for (i=0; i<size; i++) {
        printf("%02X ", buffer[i]);
    }
    printf("\n");
}

int main() {
    int rc = 0;
    size_t out_len = 0;
    unsigned char res[EVP_MAX_MD_SIZE];

    unsigned char mac_key[16] = { 0x00, 0x01 ,0x02 ,0x03, 0x04, 0x05, 0x06, 0x07,
                            0x00, 0x01 ,0x02 ,0x03, 0x04, 0x05, 0x06, 0x07};

    unsigned char msg[16] = { 0x00, 0x01 ,0x02 ,0x03, 0x04, 0x05, 0x06, 0x07,
                            0x00, 0x01 ,0x02 ,0x03, 0x04, 0x05, 0x06, 0x07};

    CMAC_CTX *cmac = CMAC_CTX_new();
    assert(cmac != NULL);

    rc = CMAC_Init(cmac, mac_key, sizeof(mac_key), EVP_aes_128_cbc(), NULL);
    assert(rc == 1);

    rc = CMAC_Update(cmac, msg, sizeof(msg));
    assert(rc == 1);

    rc = CMAC_Final(cmac, res, &out_len);
    assert(rc == 1);

    dispHex(res, out_len);

    CMAC_CTX_free(cmac);

    return 0;
}

您的配置与我使用的配置之间存在差异:

  1. OpenSSL和测试程序使用相同的编译器
  2. res的大小为EVP_MAX_MD_SIZE
  3. CMAC_Init使用sizeof(mac_key)
  4. out_len已初始化
  5. displayHex使用out_len,而非sizeof(res)
  6. 使用sizeof(res)将打印MAC的16个字节,然后打印16个乱码,因为res被声明为unsigned char res[32]。我不认为你那么远,所以记住它。

    该程序产生以下结果。我不知道这是否是纠正/预期的结果,但它会产生一个结果并打印出来:

    $ ./test.exe 
    43 91 63 0E 47 4E 75 A6 2D 95 7A 04 1A E8 CC CC 
    

    OpenSSL does not support Cygwin-x64,所以你需要使用i686版本的东西。另请参阅OpenSSL Bug Tracker上的Issue #4326: Failed to configure for Cygwin-x64

    以下是如何在Cygwin-x64下构建OpenSSL。 OpenSSL的构建脚本有一些弯曲,因此您无法使用 config 。您必须使用 Configure 并调出三元组。错误跟踪器问题仍然有效,因为config应该使事情正确。

    $ curl https://www.openssl.org/source/openssl-1.0.2f.tar.gz -o openssl-1.0.2f.tar.gz
    ...
    $ tar -xzf openssl-1.0.2f.tar.gz
    ...
    $ cd openssl-1.0.2f
    

    然后:

    $ export KERNEL_BITS=64
    $ ./Configure Cygwin-x86_64 shared no-ssl2 no-ssl3 --openssldir="$HOME/ssl"
    ...
    $ make depend
    ...
    $ make
    ...
    $ make install_sw
    

    install_sw$OPENSSLDIR/include中安装标头,在$OPENSSLDIR/lib中安装库。它不会安装手册页。

    然后编译并链接:

    $ gcc -I "$HOME/ssl/include" test.c -o test.exe "$HOME/ssl/lib/libcrypto.a"
    

    链接libcrypto.a意味着您可以避免库路径问题。事情将“适合你”。