标题:从英特尔迁移到 ARM 架构时解决 Sodium 兼容性问题
介绍
在将 PHP 应用程序从英特尔服务器迁移到基于 ARM 的服务器的过程中,Sodium 扩展出现了一个兼容性问题。遇到的具体错误是“调用未定义的函数 sodium_crypto_aead_aes256gcm_decrypt()”。
本文档概述了问题的发现并提出了使用 OpenSSL 扩展作为替代方案的解决方案。
问题发现
在调查问题时,发现 sodium_crypto_aead_aes256gcm_is_available() 函数在基于 ARM 的服务器上返回 false,表明当前环境不支持 AES-256-GCM 加密和解密。
此兼容性问题归因于 M1 芯片的 ARM 架构,因为 Sodium 扩展可能没有针对此特定架构进行优化或编译。
解决方案
为了克服兼容性问题并确保加密和解密操作的功能,OpenSSL 扩展被用作替代方案。
原始基于 Sodium 的代码已修改为使用 OpenSSL 函数进行 AES-256-GCM 加密和解密。
以下代码片段演示了使用 OpenSSL 的更新后的 aes256gcm_decrypt() 函数
function aes256gcm_decrypt($secretData, string $keygen, string $nonce)
{
$secretData = preg_replace('/[\r\n\s]/', '', $secretData);
$keygen = preg_replace('/[\r\n\s]/', '', $keygen);
$nonce = preg_replace('/[\r\n\s]/', '', $nonce);
$key = hex2bin($keygen);
$tag = substr($secretData, -32);
$ciphertext = substr($secretData, 0, -32);
try {
$plaintext = openssl_decrypt(
hex2bin($ciphertext),
'aes-256-gcm',
$key,
OPENSSL_RAW_DATA,
hex2bin($nonce),
hex2bin($tag)
);
if ($plaintext === false) {
throw new Exception('解密失败。');
}
return $plaintext;
} catch (Exception $e) {
return $e->getMessage();
}
}
解决方案的关键点
使用 preg_replace() 清理输入数据($secretData、$keygen 和 $nonce),删除换行符和空格。
使用 hex2bin() 将 $keygen 从十六进制字符串转换为二进制格式。
从 $secretData 中提取身份验证标签($tag)和密文($ciphertext)。
openssl_decrypt() 函数用于解密,并包含必要的参数,如密文、加密算法、密钥、nonce 和标签。
使用 try-catch 块实现错误处理,以捕获和返回解密过程中可能发生的任何异常。
结论
通过利用 OpenSSL 扩展并相应地修改代码,从英特尔服务器迁移到基于 ARM 的服务器时遇到的兼容性问题已成功解决。
提供的解决方案确保 AES-256-GCM 加密和解密操作可以在 ARM 架构上无缝执行。