openssl3.0 php 使用 openssl_encrypt des-ecb 加密报错 error:0308010C:digital envelope routines::unsupported

在 PHP 7.4 + OpenSSL 3.0+ 环境下使用 DES-ECB 加密时,由于 OpenSSL 3.0 默认禁用了部分弱加密算法(包括 DES),需要特殊处理才能使用。以下是解决方案:

 

解决方案(强制启用 DES-ECB)

方法 1:修改 OpenSSL 配置(推荐)

OpenSSL 3.0+ 允许通过配置文件启用遗留算法:

  1. 找到 OpenSSL 配置文件(通常位于 /etc/ssl/openssl.cnf 或 /usr/local/ssl/openssl.cnf

  2. 在 [provider_sect] 部分添加

     
    [provider_sect]
    default = default_sect
    legacy = legacy_sect
    
    [default_sect]
    activate = 1
    
    [legacy_sect]
    activate = 1
    algorithms = DES-ECB, DES-CBC
  3. 重启 PHP-FPM/Apache

     
    sudo systemctl restart php-fpm
    sudo systemctl restart apache2

    以上答案由deepseek回答,实测通过!

     

     

    方法 2:运行时指定 OpenSSL 遗留 Provider(PHP 代码)

    如果无法修改全局配置,可以在 PHP 代码中动态加载 legacy provider

    php
     
    复制
     
    下载
    private function crys($string) {
        $key = "69cc12ce"; // DES-ECB 需要 8 字节密钥(64 位)
        $cipher = "DES-ECB";
        $options = OPENSSL_RAW_DATA;
    
        // 加载 OpenSSL 3.0 遗留 Provider(兼容 DES)
        openssl_set_legacy_provider();
    
        $encrypted = openssl_encrypt($string, $cipher, $key, $options);
        return base64_encode($encrypted);
    }
    
    /**
     * 临时启用 OpenSSL 3.0 的遗留 Provider
     */
    function openssl_set_legacy_provider() {
        if (version_compare(PHP_VERSION, '7.4.0') >= 0) {
            $context = openssl_get_ssl_context_options();
            if (isset($context['ssl']['crypto_method'])) {
                $context['ssl']['crypto_method'] |= OPENSSL_CRYPTO_METHOD_DES_ECB;
            }
            openssl_set_ssl_context_options($context);
        }
    }

    方法 3:降级 OpenSSL(不推荐)

    如果可行,降级到 OpenSSL 1.1.1(默认支持 DES):

    sh
     
    复制
     
    下载
    sudo apt-get install openssl1.1

    注意事项

    1. 密钥必须是 8 字节(64 位),PHP 会自动截断或填充:

      php
       
      复制
       
      下载
      $key = substr("69cc12ce5e9d30b8", 0, 8); // 确保 8 字节
    2. DES-ECB 不安全,仅用于兼容旧系统:

      • ECB 模式 无 IV,相同明文 → 相同密文(易被破解)

      • DES 密钥太短(56 位有效密钥,易暴力破解)

    3. 推荐替代方案

      php
       
      复制
       
      下载
      // 改用 AES-256-CBC(更安全)
      $key = "69cc12ce5e9d30b8a650edb5dcfbf1d5"; // 32 字节
      $cipher = "AES-256-CBC";
      $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher));
      $encrypted = openssl_encrypt($string, $cipher, $key, OPENSSL_RAW_DATA, $iv);

    总结

    方法 适用场景 安全性
    修改 openssl.cnf 服务器可控 ⚠️ 低(DES-ECB)
    动态加载 Legacy Provider 代码可控 ⚠️ 低(DES-ECB)
    降级 OpenSSL 临时方案 ❌ 不推荐
    改用 AES-256-CBC 新项目 ✅ 高

    如果必须用 DES-ECB,建议使用方法 1 或 2,但请评估安全风险!

     

    方法2 经测试不行。方法3没有测试。

posted @ 2025-05-18 11:48  imzhi  阅读(270)  评论(0)    收藏  举报