1

我正在使用带有 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()
{
}
4

1 回答 1

2

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

OS X 提供 OpenSSL 0.9.8。它非常贫乏,现在它缺少大多数 EC 的东西,TLS 1.1,TLS 1.2,对客户端证书的良好支持等。2015 年12 月,它将进入 End of Life

您应该下载并安装 OpenSSL 1.0.2。从OpenSSL Sources 和 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

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

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

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_PATHRPATH 之类的技巧)。

您还应该考虑添加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 下它并不容易/直观。为此,请参阅如何在 Xcode 中“添加现有框架”之类的内容?

于 2015-07-07T21:59:01.773 回答