【问题标题】:Compile error when using AES/GCM in Xcode on OS X在 OS X 上的 Xcode 中使用 AES/GCM 时出现编译错误
【发布时间】:2015-09-25 10:14:12
【问题描述】:

我正在使用带有 Xcode 7 beta 2 的 OS X 10.10。我想使用来自 OpenSSL 的 AES/GCM。我想从一个例子开始,所以我从OpenSSL wiki 中拿了一个。代码如下。

代码无法编译。编译器似乎找不到以下内容:

  • EVP_aes_256_gcm
  • EVP_CTRL_GCM_SET_IVLEN
  • EVP_CTRL_GCM_GET_TAG

我认为缺少涉及 GCM 模式的项目。我该怎么办?有没有办法更新我的库或我没有导入的东西?


这是我的代码:

#include <openssl/evp.h>
#include <openssl/crypto.h>
#include <openssl/aes.h>

void handleErrors()
{
}

int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *aad,
            int aad_len, unsigned char *key, unsigned char *iv,
            unsigned char *ciphertext, unsigned char *tag)
{
    EVP_CIPHER_CTX *ctx;

    int len;

    int ciphertext_len;


    /* Create and initialise the context */
    if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

    /* Initialise the encryption operation. */
    if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
        handleErrors();

    /* Set IV length if default 12 bytes (96 bits) is not appropriate */
    if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL))
        handleErrors();

    /* Initialise key and IV */
    if(1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) handleErrors();

    /* Provide any AAD data. This can be called zero or more times as
     * required
     */
    if(1 != EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len))
        handleErrors();

    /* Provide the message to be encrypted, and obtain the encrypted output.
     * EVP_EncryptUpdate can be called multiple times if necessary
     */
    if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
        handleErrors();
    ciphertext_len = len;

    /* Finalise the encryption. Normally ciphertext bytes may be written at
     * this stage, but this does not occur in GCM mode
     */
    if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors();
    ciphertext_len += len;

    /* Get the tag */
    if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag))
        handleErrors();

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);

    return ciphertext_len;
}

int main()
{
}

【问题讨论】:

  • AES GCM 在 1.1+ openssl 分支中。 OS X (10.10.4) 附带的 libcrypto (a) 自 10.7 起已弃用,并且 (b) 仅涵盖 0.9.8zf 版本(根据 openssl version)。看起来 Common Crypto 可能值得研究。
  • 嗯...我需要我的代码在 Linux 上具有合理的可移植性... Common Crypto 是仅 OS X 的库吗?没有办法更新我的图书馆吗?
  • 更新:从 brew 我管理了看起来像最新版本的 openssl。从命令行,如果我问“openssl 版本”,我现在会得到“OpenSSL 1.0.2c 2015 年 6 月 12 日”。但 SSLeay_version 仍然输出“OpenSSL 0.9.8zf 2015 年 3 月 19 日”。现在实际上找到了我需要的函数和定义,但是链接器抱怨缺少符号。我错过了什么吗?也许包含和库路径在某处有误?
  • CC 仅适用于 OSX(坦率地说,如果它提供 GCM,我会感到惊讶,因为我并没有真正寻找它)。更新到更高版本的 openssl 肯定是合理的,特别是如果其他人已经为您完成了这项工作(看起来像 brew 一样)。您可能必须链接到不同的 dylib,或者只使用静态库,无论哪种情况,都需要使用 brew 安装的版本;不是安装了 OS X 的那个。在那场狩猎中祝你好运,因为我不使用 brew,因此无法说出它被丢弃的位置。
  • 好的,所以...当我说“-lcrypto”时,我指的是可能位于我系统中任何位置的 libcrypto.dylib 文件?没有办法追查吗?因为我知道在哪里可以找到新的,由 brew 安装...

标签: c++ xcode macos openssl aes-gcm


【解决方案1】:

我认为缺少涉及 GCM 模式的项目。我该怎么办?有没有办法更新我的库或我没有导入的东西?

OS X 提供 OpenSSL 0.9.8。它现在非常贫乏,而且它缺乏大多数 EC 的东西,TLS 1.1、TLS 1.2、对客户端证书的良好支持等。在December, 2015, it will enter End of Life

您应该下载并安装 OpenSSL 1.0.2。从OpenSSL Sources and Tarballs 下载。解压,然后(大部分取自 OpenSSL 的 Compilation and Installation):

cd openssl-1.0.2

export KERNEL_BITS=64
./config no-ssl2 no-ssl3 enable-ec_nistp_64_gcc_128 --openssldir=/usr/local/ssl/macosx-x64/
make
make test
sudo make install

对于 64 位架构,您必须手动添加 enable-ec_nistp_64_gcc_128,因为 Configure 无法自行确定。

然后,执行dclean,并可选择构建 32 位:

export KERNEL_BITS=32
make clean && make dclean
./config no-ssl2 no-ssl3 --openssldir=/usr/local/ssl/macosx-x86/
make
make test
sudo make install

在上面,shared 被省略了。这是因为 Apple 链接器始终使用共享对象,即使您尝试指定静态存档。共享库也会给您带来麻烦,因为 Apple 的 dylib 版本会在您的版本之前找到(除非您使用 DYLD_LIBRARY_PATH 或 RPATH 之类的技巧)。

您还应该考虑添加no-comp,因为我们知道在某些情况下会出现压缩泄漏信息。 CRIMEBREACH是信息泄露的两个示范。

最后,你应该建立一个胖库。事实上,构建系统不允许通过添加-arch i386 -arch x86_64(需要手动修改Makefile.org)。它破坏了 ar 命令 IIRC。如果您可以构建一个胖库,或者使用lipo 创建一个胖库,那么opensslconf.h 对于其中一个平台是不正确的。


为 x86_64 使用这些 Xcode Build Settings 设置:

  • 始终搜索用户路径:NO
  • 标题搜索路径:/usr/local/ssl/macosx-x64/include
  • 图书馆搜索路径:/usr/local/ssl/macosx-x64/lib

并为 i386 使用这些 Xcode Build Settings 设置:

  • 始终搜索用户路径:NO
  • 标题搜索路径:/usr/local/ssl/macosx-x86/include
  • 图书馆搜索路径:/usr/local/ssl/macosx-x86/lib

请务必指定libcrypto.a 库,否则会出现链接器错误。在 Xcode 下它并不容易/直观。为此,请参阅How to “add existing frameworks” in Xcode?

【讨论】:

    猜你喜欢
    • 2014-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-20
    • 1970-01-01
    • 1970-01-01
    • 2014-03-15
    • 2012-08-28
    相关资源
    最近更新 更多