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

IIS环境下PHP连接启用Always Encrypted的Arabic_CI_AS数据库报错

问题描述

尝试访问启用Always Encrypted的SQL Server数据库时,IIS环境下运行PHP代码报错,但CMD环境下相同代码可正常执行,后续错误变更为“密钥集找不到”,疑似与数据库Arabic_CI_AS排序规则及加密后列的Arabic_BIN2排序规则兼容问题相关。

操作流程

  • 在SQL Server中为目标表启用列加密;
  • 数据库内验证:启用Always Encrypted后可正常返回解密数据;
  • 编写PHP代码(如下);
  • 运行代码报错,CMD环境下测试相同代码无异常。
<?php
$hostname_DB= "localhost"; 
$database_DB= "test";
$username_DB= "***";                                         
$password_DB= "***";    

try {
    $connection = new PDO("sqlsrv:Server=$hostname_DB;Database=$database_DB;ColumnEncryption = Enabled;LoginTimeout=100000", $username_DB, $password_DB);
        $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $connection->setAttribute(PDO::SQLSRV_ATTR_QUERY_TIMEOUT, 1000000);

    $query="select TOP (10) second_name_a FROM employees";
    $stmt = $connection->query($query);

    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        print_r($row);echo'<br>';

    }
} catch (PDOException $e) {
    die("Connection failed: " . $e->getMessage());
}

?>

错误信息

  1. 初始错误:

Connection failed: SQLSTATE[CE100]: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]The system cannot find the file specified.

  1. 更新后(2023/5/17)错误:

密钥集找不到

环境信息

  • 运行环境:IIS(Internet Information Services)+PHP 8.0.6
  • 已安装并启用Microsoft Drivers for PHP for SQL Server扩展:php_pdo_sqlsrv_80_ts_x64.dll/php_sqlsrv_80_ts.dll

已尝试的无效操作

  • 重启SQL Server
  • 启用Named Pipes
  • 检查用户连接权限

关键观察(更新信息)

  • 2023/5/15:测试排序规则为SQL_Latin1_General_CP1_CI_AS的数据库可正常运行,推测问题与Arabic_CI_AS排序规则有关,但无法转换该数据库排序规则;启用Always Encrypted后,列排序规则变为Arabic_BIN2,存在兼容问题。

解决方案建议

1. 修复IIS与CMD的权限差异问题

CMD运行正常但IIS报错,核心原因是IIS应用池身份无Always Encrypted密钥存储的访问权限:

  • 打开IIS管理器,找到对应站点的应用池,查看其身份(默认是ApplicationPoolIdentity或Network Service);
  • 若使用Windows证书存储:
    1. 打开certlm.msc(本地计算机证书存储),找到Always Encrypted用的列主密钥证书;
    2. 右键证书→所有任务→管理私钥;
    3. 添加应用池身份(格式为IIS AppPool\你的应用池名称),授予读取权限;
  • 若使用Azure Key Vault等外部密钥存储,确保应用池身份拥有Get、UnwrapKey等必要权限。

2. 处理排序规则兼容问题

针对Arabic_CI_AS数据库及Arabic_BIN2加密列的兼容问题:

  • 升级ODBC Driver 17 for SQL Server至最新版本,旧版本对非拉丁排序规则的加密列支持有限;
  • 在PHP连接字符串中显式指定数据库排序规则:
    $connection = new PDO("sqlsrv:Server=$hostname_DB;Database=$database_DB;ColumnEncryption = Enabled;LoginTimeout=100000;ConnectionCollation=Arabic_CI_AS", $username_DB, $password_DB);
    
  • 验证密钥元数据状态:执行以下SQL确认列主密钥和列加密密钥正常启用:
    SELECT name, is_enabled FROM sys.column_master_keys;
    SELECT name, is_enabled FROM sys.column_encryption_keys;
    

3. 排查“密钥集找不到”错误

该错误多与私钥访问权限或证书位置相关:

  • 确认列主密钥证书存储在本地计算机存储(而非当前用户存储),IIS应用池身份默认无法访问当前用户的证书存储;
  • 若证书为导入所得,确保导入时勾选“允许私钥被导出”(仅用于排查,生产环境可取消),且私钥未损坏;
  • 运行certutil -store My命令,检查本地计算机个人存储中的证书是否存在、私钥状态正常。

4. 其他排查步骤

  • 启用ODBC驱动日志:打开ODBC数据源管理器(64位)→跟踪选项卡→勾选“启动ODBC跟踪”并设置日志路径,运行代码后查看日志定位具体失败点;
  • 确认PHP扩展配置正确:确保php.ini中启用的扩展版本与PHP 8.0.6 x64完全匹配,无32/64位扩展混用情况;
  • 测试基础连接:在IIS中运行无加密的简单查询,确认数据库基础连接正常,排除IIS本身配置问题。

内容的提问来源于stack exchange,提问作者Hesham Mahmoud

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 03:08:18