Openssl Solaris上的AES_ctr128_encrypt与其他操作系统的解密方式不同';s

Openssl Solaris上的AES_ctr128_encrypt与其他操作系统的解密方式不同';s,openssl,aes,endianness,encryption-symmetric,Openssl,Aes,Endianness,Encryption Symmetric,我已经从openssl-1.0.1g为各种平台编译了libcrypto.so共享库。通过使用共享库,我的应用程序能够在以下任意一个应用程序之间加密/解密数据: Linux i386 Linux x86_64 Linux PPC AIX RISC 它们可以解密自己的数据,但不能相互解密,也不能解密上述任何数据: Solaris i386 Solaris SPARC 我最初认为这是一个endian问题,但AIX/RISC和Linux/PPC是,它们似乎与Linux i386和x86_64(L

我已经从openssl-1.0.1g为各种平台编译了libcrypto.so共享库。通过使用共享库,我的应用程序能够在以下任意一个应用程序之间加密/解密数据:

  • Linux i386
  • Linux x86_64
  • Linux PPC
  • AIX RISC
它们可以解密自己的数据,但不能相互解密,也不能解密上述任何数据:

  • Solaris i386
  • Solaris SPARC
我最初认为这是一个endian问题,但AIX/RISC和Linux/PPC是,它们似乎与Linux i386和x86_64(LE)配合得很好

Solaris系统包括:

SunOS pluto 5.9 Generic_Virtual sun4u sparc SUNW,SPARC-Enterprise-T5120
SunOS nemo 5.9 Generic_118559-11 i86pc i386 i86pc
libcrypto.so是通过以下方式编译的:

#[openssl-1.0.1g] ./Configure solaris-sparcv9-cc shared 
#[openssl-1.0.1g] ./Configure solaris-x86-cc shared
请注意,Solaris系统都使用“/opt/SUNWspro/bin/cc”作为编译器,其他所有系统都使用“gcc”

我已经验证,在加密和解密时,我总是以相同的IV/计数器和符号密钥开始。加密例程很好地嵌入到我的程序中,但这基本上就是我所做的全部:

uchar ivec[AES_BLOCK_SIZE], ecount[AES_BLOCK_SIZE], symkey[16];
uint num = 0, bits = 128;
uchar *buf, *ebuf; /* these are malloc'd and buf set to data to encrypt/decrypt */
...
memcpy(symkey, MYTESTKEY, 16);
memset(ecount, 0, AES_BLOCK_SIZE);
memset(ivec, 0, AES_BLOCK_SIZE);
memcpy(ivec, SOMEDATA, 8); /* from RAND_seed() and RAND_bytes() */
AES_set_encrypt_key(symkey, bits, &outkey);
...
AES_ctr128_encrypt(inp, outp, bytes, key, ivec, ecount, &num);
同样,在同一系统上进行加密/解密时,此功能始终有效,只有在其中一个系统为Solaris时才会解码为垃圾邮件。不过,我使用的是非常旧的Solaris操作系统和机箱,因为我必须保持向后兼容性。
提前谢谢

请使用更高端的OpenSSL功能

例如,由一名核心开发人员进行检查:

无法保证低级别密码上下文(或任何类似的上下文 上下文)将在不同平台上保持相同。Endian差异、填充和 平台特定优化可在机器上产生不同的数据 水平。在适当的平台上使用上下文的结果应该是 不过,显然要保持一致


只是为了更新,我转换为执行副总裁,但没有区别。我用GCC重新编译了libcrypto.so,也没有任何区别(使用solaris64-sparcv9-GCC),直到我从/usr/bin中删除了到cc的链接。然后我再次使用GCC重新编译,这次它成功了。我没有时间进一步研究,但这意味着即使在指定了*-gcc之后,一些对象仍在使用cc进行编译。不幸的是,我们的旧Solaris-x86 V9系统没有GCC可用,因此我们将不再支持intel上的V9。

什么是
MYTESTKEY
?是16字节吗?
strcpy(symkey,MYTESTKEY)
之前的
memset(symkey,0x00,sizeof(symkey))
对这种情况有帮助吗?是的,这只是我正在使用的代码的简单示例。MYTESTKEY和SOMEDATA可以是任何数据,但加密和解密都是相同的。很抱歉,我匆忙提供了一个简单的例子,当我打算使用memcpy时,我使用了strcpy,所以我编辑了上面的问题。CTR本质上是一种流模式。那么,您看到的是不同平台的前N个密码字符的匹配,还是完全不同?如果使用NULL键和NULL nonce(即0x00的字符串),是否可以复制?好的,我总是从最高8字节的随机IV开始,就像在我的示例中一样,但使用相同的键。我验证了在客户端使用相同的密钥和IV进行解密。但是由于IV每次都不同,垃圾输出也不同。如果第一个块与计数器有关,我可能会期望它能够正确解密,然后获取垃圾,但我会获取整个消息的垃圾。因此,我将key和IV都设置为nulls,我仍然会得到垃圾(同样只在solaris和其他任何东西之间),但至少每次垃圾都是一样的;如果编译过程中包含了solaris-x86-cc-DL_ENDIAN。否则,我认为Andy或Henson博士(或者其他OpenSSL开发者)应该参与进来。我会先问一下,然后问openssl-users是否有用户。这是一个很好的发现。令人遗憾的是,这正是他们对作为公共界面一部分的功能所采取的立场。为完整起见,《FIPS用户指南》并未说明(使用
EVP.*
功能)的限制。这让我想知道什么东西坏在哪里,为什么它只在开发者邮件列表中提到……当我们写这篇文章时,CTR没有在EVP中启用,我们使用了许多公认的AES_ctr128_encrypt()示例。Solaris是后来添加的,但我不能说直到现在我们是否需要在Solaris和其他系统之间进行测试(我们一直在AIX和Linux之间进行测试)。在这个级别上对代码进行更改并不容易,因为我们只想更新到最新的加密库,因为我们的SSL版本包含heartbleed bug(尽管我们不使用heartbeat函数)。也许我会先找到一个GCC,它将在这些旧的SunOS机器上运行,看看它是否有效。啊,请阅读您提到的消息中的代码。也许这根本不是CTR的问题,但是AES\u set\u encrypt\u key()。如果是这样的话,我本以为这个问题会蔓延得更广,特别是因为那条评论是从2012年开始的。没错,但如果EVP功能运行,那么该功能可能是预期的。不要让我开始了解OpenSSL的文档或代码质量。这是心脏出血之前的一个问题,可能是原因之一。