【发布时间】: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