【问题标题】:Same C code producing different results on Mac OS X than Windows and Linux相同的 C 代码在 Mac OS X 上产生的结果与在 Windows 和 Linux 上不同
【发布时间】:2010-08-03 22:42:57
【问题描述】:

我正在使用旧版本的 OpenSSL,但在尝试使用跨平台代码时,我遇到了一些困扰我好几天的行为。

我有代码调用 OpenSSL 来签署一些东西。我的代码以 ASN1_sign 中的代码为模型,该代码位于 OpenSSL 的 a_sign.c 中,当我使用它时会出现相同的问题。这是相关的代码行(在 a_sign.c 中找到并使用完全相同的方式):

EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl);

ctx 是 OpenSSL 使用的结构,与本次讨论无关
buf_in 是要签名的数据的 char*
inl 是 buf_in 的长度

在调用 EVP_SignFinal 签名之前,可以重复调用 EVP_SignUpdate 以读入要签名的数据。

在 Ubuntu 和 Windows 7 上使用此代码时一切正常,在给定相同输入的情况下,它们都产生完全相同的签名。

在 OS X 上,如果 inl 的大小小于 64(即 buf_in 中有 64 个字节或更少),那么它也会产生与 Ubuntu 和 Windows 相同的签名。但是,如果 inl 的大小变得大于 64,它会产生自己的内部一致签名,这与其他平台不同。 内部一致是指 Mac 将读取签名并验证它们是否正确,而它会拒绝来自 Ubuntu 和 Windows 的签名,反之亦然。

我设法解决了这个问题,并通过将上面的那一行更改为以下内容来创建相同的签名,它一次读取一个字节的缓冲区:

int input_it;
for(input_it = (int)buf_in; input_it < inl + (int)buf_in; intput_it++){
  EVP_SIGNUpdate(&ctx, (unsigned char*) input_it, 1);
}

这导致 OS X 拒绝它自己的大于 64 字节的数据签名为无效,我在其他地方追踪了一条类似的线路来验证需要以相同方式分解的签名。

这修复了签名创建和验证,但仍然有问题,因为我遇到了其他问题,我真的不想更深入地研究(和修改!)OpenSSL。

我肯定做错了什么,因为我在使用库存 ASN1_sign 时遇到了完全相同的问题。这是我编译 OpenSSL 的方式的问题吗?对于我的生活,我无法弄清楚。谁能告诉我我必须犯什么愚蠢的错误?

【问题讨论】:

    标签: macos cross-platform openssl


    【解决方案1】:

    这可能是 MacOS 实现中的一个错误。我建议您按照http://www.openssl.org/support/faq.html#BUILD17 中所述将上述文本发送给开发人员来提交错误

    【讨论】:

      【解决方案2】:

      Mac 上的 OpenSSL 存在已知问题(您必须跳过几个环节才能确保它与正确的库而不是系统库链接)。你自己编译的吗?发行版中的问题文件解释了问题的详细信息并提出了一些解决方法。 (或者,如果您使用共享库运行,请仔细检查您的 DYLD_LIBRARY_PATH 是否设置正确)。不能保证,但这看起来可能是一个开始的地方......

      【讨论】:

        【解决方案3】:

        移植 Windows 和 Linux 代码的最常见问题是内存的默认值。我认为 Windows 将其设置为 0xDEADBEEF 而 Linux 将其设置为 0s。

        【讨论】:

          猜你喜欢
          • 2021-07-16
          • 1970-01-01
          • 1970-01-01
          • 2018-02-13
          • 2013-05-20
          • 1970-01-01
          • 1970-01-01
          • 2016-09-16
          • 1970-01-01
          相关资源
          最近更新 更多