PHP 怎么PHP Libsodium

wen PHP项目 2

PHP Libsodium 使用指南

Libsodium 是一个现代、易用的加密库,PHP 从 7.2 开始默认内置了对它的支持。

PHP 怎么PHP Libsodium

检查是否已安装

// 检查扩展是否可用
if (extension_loaded('sodium')) {
    echo "Libsodium 扩展已加载";
}
// 查看版本
echo SODIUM_LIBRARY_VERSION;

基本加密/解密

对称加密 (SecretKey)

// 生成密钥
$key = sodium_crypto_secretbox_keygen();
// 加密
$message = "这是一条秘密消息";
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$ciphertext = sodium_crypto_secretbox($message, $nonce, $key);
// 解密
$decrypted = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);
echo $decrypted; // 输出:这是一条秘密消息

非对称加密

生成密钥对

// Alice 生成密钥对
$alice_keypair = sodium_crypto_box_keypair();
$alice_secret = sodium_crypto_box_secretkey($alice_keypair);
$alice_public = sodium_crypto_box_publickey($alice_keypair);
// Bob 生成密钥对
$bob_keypair = sodium_crypto_box_keypair();
$bob_secret = sodium_crypto_box_secretkey($bob_keypair);
$bob_public = sodium_crypto_box_publickey($bob_keypair);

加密消息

// Alice 给 Bob 发送加密消息
$message = "这是给Bob的私密消息";
$nonce = random_bytes(SODIUM_CRYPTO_BOX_NONCEBYTES);
// 使用Bob的公钥和Alice的私钥加密
$ciphertext = sodium_crypto_box(
    $message,
    $nonce,
    $alice_secret . $bob_public
);
// Bob 解密(使用Bob的私钥和Alice的公钥)
$decrypted = sodium_crypto_box_open(
    $ciphertext,
    $nonce,
    $bob_secret . $alice_public
);

密码哈希

// 哈希密码
$password = "用户密码123";
$hash = sodium_crypto_pwhash_str(
    $password,
    SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
    SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);
// 验证密码
if (sodium_crypto_pwhash_str_verify($hash, $password)) {
    echo "密码验证成功";
}
// 判断是否需要重新哈希
if (sodium_crypto_pwhash_str_needs_rehash(
    $hash,
    SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE,
    SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE
)) {
    // 重新哈希
    $new_hash = sodium_crypto_pwhash_str(
        $password,
        SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE,
        SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE
    );
}

签名验证

// 生成签名密钥对
$sign_keypair = sodium_crypto_sign_keypair();
$secret_key = sodium_crypto_sign_secretkey($sign_keypair);
$public_key = sodium_crypto_sign_publickey($sign_keypair);
// 签名消息
$message = "这是需要签名的消息";
$signed_message = sodium_crypto_sign($message, $secret_key);
// 验证并提取原始消息
$original = sodium_crypto_sign_open($signed_message, $public_key);
if ($original !== false) {
    echo "签名验证成功:" . $original;
}

安全随机数生成

// 生成随机字节
$random_bytes = random_bytes(32);
// 生成随机整数
$random_int = random_int(1, 100);
// 生成用于加密的随机数
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);

完整示例:用户密码加密存储

class UserAuth {
    public static function hashPassword(string $password): string {
        return sodium_crypto_pwhash_str(
            $password,
            SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE,
            SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE
        );
    }
    public static function verifyPassword(string $password, string $hash): bool {
        return sodium_crypto_pwhash_str_verify($hash, $password);
    }
    public static function needsRehash(string $hash): bool {
        return sodium_crypto_pwhash_str_needs_rehash(
            $hash,
            SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE,
            SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE
        );
    }
}
// 使用示例
$password = "secure_password_123";
$hash = UserAuth::hashPassword($password);
echo "哈希结果: " . $hash . "\n";
if (UserAuth::verifyPassword("wrong_password", $hash)) {
    echo "密码正确";
} else {
    echo "密码错误";
}

安全注意事项

// ✅ 正确:每次使用新的随机 nonce
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
// ❌ 错误:重复使用 nonce
$nonce = "fixed_nonce_12345678";
// ✅ 正确:使用常量比较
if (hash_equals($hash1, $hash2)) {
    echo "相等";
}
// ❌ 错误:使用普通比较(易受时序攻击)
if ($hash1 === $hash2) {
    echo "相等";
}
// ✅ 正确:使用后会销毁敏感数据
sodium_memzero($secret_key);

性能优化建议

// 使用不同的安全级别
$opslimit_interactive = SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE;  // 用于交互式登录
$opslimit_moderate = SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE;       // 中等安全
$opslimit_sensitive = SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE;     // 高安全(慢)
// 密码哈希示例
$hash = sodium_crypto_pwhash_str(
    $password,
    $opslimit_moderate,  // 根据场景选择合适的级别
    SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE
);

常见错误处理

try {
    // 验证输入长度
    if (mb_strlen($key, '8bit') !== SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
        throw new Exception("密钥长度不正确");
    }
    // 执行加密操作
    $ciphertext = sodium_crypto_secretbox($message, $nonce, $key);
} catch (Exception $e) {
    // 处理错误
    error_log("加密失败: " . $e->getMessage());
    // 不要暴露具体的错误信息给用户
    echo "处理失败";
} finally {
    // 清理敏感数据
    sodium_memzero($key);
}

Libsodium 提供了现代、安全的加密功能,相比 mcrypt 等旧库更推荐使用。

抱歉,评论功能暂时关闭!