標題:解決從 Intel 遷移到 ARM 架構時的 Sodium 相容性問題
簡介
在將 PHP 應用程式從基於 Intel 的伺服器遷移到基於 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();
}
}
解決方案的重點
輸入資料($secretData、$keygen 和 $nonce)會透過使用 preg_replace() 移除換行字元和空白字元來清理。
$keygen 會使用 hex2bin() 從十六進位字串轉換為二進位格式。
身份驗證標籤 ($tag) 和密文 ($ciphertext) 會從 $secretData 中提取。
openssl_decrypt() 函式用於解密,其中包含必要的參數,例如密文、加密演算法、金鑰、nonce 和標籤。
使用 try-catch 區塊實作錯誤處理,以捕獲並回傳解密過程中可能發生的任何例外。
結論
透過利用 OpenSSL 擴充功能並相應地修改程式碼,成功解決了從基於 Intel 的伺服器遷移到基於 ARM 的伺服器時遇到的相容性問題。
提供的解決方案確保了 AES-256-GCM 加密和解密操作可以在 ARM 架構上順利執行。