You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CodeIgniter3项目中集成并使用Sodium AES 256加密

我刚好在几个月前给一个运行中的CodeIgniter 3项目集成过Sodium AES-256加密,踩过一些坑,分享一下亲测有效的完整流程,应该能帮到你:

前置检查

首先确认你的PHP 7.4环境已经启用Sodium扩展:

  • 运行php -m | grep sodium,如果输出sodium则说明已启用;
  • 或者在CI项目中新建一个测试控制器,调用var_dump(extension_loaded('sodium')),返回true即可。
    如果未启用,在php.ini中添加对应配置:
  • Linux:extension=sodium.so
  • Windows:extension=sodium
创建Sodium加密库

在CI3的application/libraries/目录下新建Sodium_encryption.php,这是我们封装的加密工具类,专门实现AES-256-GCM加密(Sodium官方推荐的AES-256实现方式):

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Sodium_encryption {

    private $key;

    public function __construct() {
        $this->CI =& get_instance();
        // 从配置中读取密钥(建议通过环境变量存储)
        $this->key = $this->CI->config->item('sodium_encryption_key');
        
        // 前置验证
        if (!$this->key || !sodium_crypto_aead_aes256gcm_is_available()) {
            show_error('Sodium AES-256-GCM 不可用或密钥未配置');
        }
        if (strlen($this->key) !== SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES) {
            show_error('Sodium 密钥必须为32字节长度');
        }
    }

    /**
     * 加密明文内容
     * @param string $plaintext 要加密的内容
     * @return string base64编码后的加密串(包含随机nonce+密文+验证标签)
     */
    public function encrypt($plaintext) {
        // 生成12字节的随机nonce(每个加密请求必须唯一)
        $nonce = sodium_randombytes_buf(SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES);
        // 执行加密
        $ciphertext = sodium_crypto_aead_aes256gcm_encrypt(
            $plaintext,
            '', // 可选附加数据,加密解密需保持一致
            $nonce,
            $this->key
        );
        
        // 拼接nonce和密文后base64编码,方便存储/传输
        $encrypted = base64_encode($nonce . $ciphertext);
        // 清理内存中的敏感数据
        sodium_memzero($plaintext);
        sodium_memzero($nonce);
        
        return $encrypted;
    }

    /**
     * 解密加密串
     * @param string $encrypted base64编码的加密串
     * @return string|false 解密后的明文,验证失败返回false
     */
    public function decrypt($encrypted) {
        $decoded = base64_decode($encrypted);
        if (!$decoded) return false;
        
        // 拆分nonce(前12字节)和密文
        $nonce = substr($decoded, 0, SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES);
        $ciphertext = substr($decoded, SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES);
        
        // 执行解密并验证
        $plaintext = sodium_crypto_aead_aes256gcm_decrypt(
            $ciphertext,
            '', // 需和加密时的附加数据一致
            $nonce,
            $this->key
        );
        
        // 清理敏感数据
        sodium_memzero($ciphertext);
        sodium_memzero($nonce);
        
        return $plaintext;
    }

    /**
     * 生成符合要求的密钥(仅用于初始化,生成后务必保存到环境变量)
     * @return string 32字节的随机密钥
     */
    public static function generate_key() {
        return sodium_crypto_aead_aes256gcm_keygen();
    }
}
配置密钥
  1. 生成密钥:在命令行执行以下命令,得到一个32字节的密钥字符串:
php -r "echo sodium_crypto_aead_aes256gcm_keygen().PHP_EOL;"
  1. 将密钥存储到服务器环境变量中(不要硬编码到代码里,避免泄露);
  2. 在CI3的application/config/config.php中添加配置项:
$config['sodium_encryption_key'] = getenv('SODIUM_ENCRYPTION_KEY');
在CI3中使用

你可以选择全局自动加载,或者在需要的控制器中手动加载:

  • 全局自动加载:在application/config/autoload.php中,把sodium_encryption添加到$autoload['libraries']数组;
  • 手动加载:在控制器中调用:
$this->load->library('sodium_encryption');

使用示例:

// 加密示例
$original_content = '用户敏感数据,比如手机号、身份证号';
$encrypted_content = $this->sodium_encryption->encrypt($original_content);

// 解密示例
$decrypted_content = $this->sodium_encryption->decrypt($encrypted_content);
if ($decrypted_content === false) {
    // 处理解密失败(比如内容被篡改)
    show_error('内容验证失败,可能已被篡改');
}
注意事项
  • 密钥绝对不能提交到版本控制,必须通过环境变量管理;
  • 同一个明文每次加密结果都不一样(因为nonce随机),这是正常且安全的;
  • 如果解密返回false,说明加密串被篡改或密钥不正确,需要做异常处理;
  • 用完敏感数据后,一定要用sodium_memzero()清理内存,防止内存泄露。

内容的提问来源于stack exchange,提问作者Nazeer Shaik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 16:18:11