无法使用Cygwin和OpenSSL计算CMAC

我想使用OpenSSL计算CMAC。 我发现这个问题对我很有帮助。

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

#include  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 -LC:/OpenSSL-Win32 -llibeay32 -IC:/OpenSSL-Win32/include编译它,它生成test_cmac.exe没有问题。

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

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

即使我添加printf("..."); 在CMAC计算之前,它以相同的方式进行。

奇怪的是,以下程序:

 #include  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 -LC:/OpenSSL-Win32 -llibeay32 -IC:/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\

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

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

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

以下适合我,但有一些差异:

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

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

  1. OpenSSL和测试程序都使用相同的编译器
  2. res的大小为EVP_MAX_MD_SIZE
  3. CMAC_Init使用sizeof(mac_key)
  4. out_len已初始化
  5. displayHex使用out_len ,而不是sizeof(res)

使用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不支持Cygwin-x64 ,因此您需要使用i686版本的东西。 另请参阅问题#4326:无法在OpenSSL Bug Tracker上配置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意味着您可以避免库路径问题。 事情将“适合你”。

查看CMAC_Init ,似乎未执行CMAC对象的初始化,因为IMPLNULL

 int 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; }