Endianness和C API:特别是OpenSSL

Has*_*yed 3 c++ encryption algorithm portability endianness

我有一个使用以下OpenSSL调用的算法:

HMAC_update() / HMAC_final() // ripe160
EVP_CipherUpdate() / EVP_CipherFinal() // cbc_blowfish
Run Code Online (Sandbox Code Playgroud)

这些算法采用了unsigned char *"纯文本".我的输入数据来自C++ std::string::c_str(),它源自协议缓冲区对象,作为编码的UTF-8字符串.UTF-8字符串意味着是endian neutrial.然而,我对OpenSSL如何对数据执行操作有点偏执.

我的理解是加密算法适用于8位数据块,如果unsigned char *在执行操作时a 用于指针算术,算法应该是endian中性的,我不需要担心任何事情.我的不确定性因为我正在使用小端机器并且从未进行任何真正的跨架构编程而更加复杂.

我的信念/推理是基于以下两个属性

  1. std :: string(不是wstring)在内部使用8位ptr,c_str()无论CPU架构如何,生成的ptr都会以相同的方式进行迭代.
  2. 加密算法可以是设计,也可以是实现,endian中立.

我知道获得明确答案的最佳方法是使用QEMU并进行一些跨平台的单元测试(我打算这样做).我的问题是要求对我的推理进行评论,或许在面临类似问题时可以帮助其他程序员.

Ste*_*sop 7

UTF-8字符串和std :: string都定义为字符序列.加密算法被定义为在一个字节/八位字节序列上运行(在C字节中是相同的字符,如果你的字节不是一个八位字节那么你就是一个不寻常的实现,你可能需要有点小心处理UTF-8).在连续存储器中表示字节序列的唯一合理方法是第一个在最低地址,而后续在高地址(C数组).加密算法不关心字节代表什么,所以你很好.

Endian-ness只对你处理像a这样的东西很重要int,这本身并不是一个字节序列.在摘要中,它只是"东西",它将值INT_MIN保存到INT_MAX.当你在内存中代表这样的野兽时,它当然必须是一些字节,但没有一种方法可以做到.

实际上,如果您(可能通过您调用的东西)将char*重新解释为int*,反之亦然,或者定义一个使用一系列chars表示int的协议,则endian-ness在C中很重要.如果你只处理字符数组,或只处理整数数组,那就无关紧要了,因为字节序是int的属性,而其他类型的字符大于char.