OpenSSL报certificate rejected:error 28与CA辅助信任属性排查

根证书已经放进CAfile,证书没过期,OpenSSL却报certificate rejected。先别急着下载另一份fullchain:这里的rejected不等于revoked。前者可能是本地信任材料明确拒绝某种用途,后者才是吊销检查的结果。本文用隔离证书区分error 28、辅助信任属性和证书本体。

一、先读完整错误,不把28当成吊销

OpenSSL的X509_V_ERR_CERT_REJECTED表示根CA被标记为拒绝指定用途。它与error 23的certificate revoked、error 20的构链失败、error 26的用途不兼容不是同一个问题。错误编号也不是Shell进程退出码:本轮28对应verify退出2。

临时根直签叶子的实验在depth 1报错;存在中间CA时层级会变。先把错误前的subject与实际路径对应,不把所有depth 1都叫根。

二、先确认读到的CA文件和运行版本

记录运行版本、工作目录及CAfile绝对路径。终端、容器和服务可能读取不同材料。下面root-reject.pem是单张CA工作副本,不是系统文件。

bash 复制代码
openssl version -a
openssl x509 -in root-reject.pem -noout -text

在文本末尾找Trusted Uses与Rejected Uses。实验中的拒绝属性显示TLS Web Server Authentication。PEM头可能是BEGIN TRUSTED CERTIFICATE,但这个词不是"安全通行证":它也能封装明确拒绝用途的属性。

x509通常只读取首张证书。CA包里有多张时,应逐张核对条目、指纹、来源与辅助属性;只看到第一张正常,不能断言整包无拒绝项。不要将原始日志中的内部名称、路径和业务标识直接公开。

三、把验证用途写清楚,再复现同一故障

下例假定已准备PEM叶证书leaf.pem、单张根CA工作副本,并且叶子名称是占位域名service.example。若有中间CA,需要另提供-untrusted链材料;本例是根直签,不能照搬成缺中间证书的生产配置。

bash 复制代码
openssl verify -no-CApath -CAfile root-reject.pem \
  -purpose sslserver -verify_hostname service.example leaf.pem

-purpose sslserver检查服务器用途,-verify_hostname检查名称,-no-CApath避免默认CA目录掩盖对照。显式CAfile固定本次文件来源,但仍要留意构建、配置与应用自己的验证选项。OpenSSL从1.1.0起,未单独指定信任模型时会从purpose推导模型。

本轮在1.1.1k FIPS构建中,把-purpose删掉后同一拒绝材料竟能通过。这个"绿灯"不是修好了,而是测试条件变了。排障最怕把考题删掉,再宣布满分。正式验收应与应用用途一致,不用取消用途检查解决28。

四、为什么指纹相同,验证结果却不同

OpenSSL辅助信任属性保存在本地可信证书表示中,不是CA签名覆盖的X.509扩展。证书本体相同,不代表本地信任决策相同;只比SHA-256证书指纹会漏掉这一层。

下面只在独立实验目录对临时CA副本添加拒绝项,不能对系统或生产CA执行。root.pem须是已有的实验CA,命令不创建完整PKI,也不是让读者把真实根证书加入黑名单。

bash 复制代码
openssl x509 -in root.pem -addreject serverAuth \
  -trustout -out root-reject.pem
openssl x509 -in root-reject.pem -noout -sha256 -fingerprint
openssl x509 -in root.pem -noout -sha256 -fingerprint

本轮两份证书的指纹与证书DER均相同,带serverAuth拒绝项的材料却验证失败。辅助属性不是证书签名或叶子EKU。指纹确认对象,辅助属性确认本地策略,要一起留档。

五、用正反例区分策略问题与用途扩展

实验用临时RSA根直签一张同时具有serverAuth和clientAuth用途的叶证书,排除叶子EKU干扰。下表是本轮离线结果,不代表所有TLS后端、系统证书库或浏览器行为。

根CA工作副本 验证条件 本轮结果
没有辅助属性 sslserver 通过,退出0
拒绝serverAuth sslserver error 28,depth 1,退出2
拒绝clientAuth sslserver 通过,退出0
拒绝clientAuth sslclient error 28,退出2
同时信任和拒绝serverAuth sslserver 仍为error 28

再加一个trusted用途并不能抵消同用途的reject。也不要把Rejected Uses与证书里的Extended Key Usage混为一谈:前者描述本地信任政策,后者是签名证书中的扩展;两者都可能影响验证,但修复责任与材料来源不同。

六、修复靠授权来源,不靠清掉拒绝项

如果拒绝项来自组织策略、CA撤信任或安全事件,应停止使用该信任路径,联系证书与信任库维护者确定允许的替代链。若是配置误发,也应从受控来源恢复经过批准的材料,记录变更原因和回滚版本,而不是在客户端偷偷放宽政策。

尤其小心"转一下PEM格式"。x509默认输出普通证书时可能丢弃辅助信任设置;本轮把拒绝材料普通读写后,服务器验证确实变成通过。这证明策略丢了,不证明风险消失。需要保留可信表示时核对-trustout与完整属性,别把格式转换当解除拒绝的捷径。

下例在可信、任务专用目录运行,root-approved.pem来自已批准来源;日志路径不能被其他用户写入,避免覆盖业务文件或跟随不可信软链接。

bash 复制代码
if openssl verify -no-CApath -CAfile root-approved.pem \
  -purpose sslserver -verify_hostname service.example \
  leaf.pem >verify.log 2>&1; then
  printf '%s\n' '离线链验证通过,仍需验收真实HTTPS'
else
  rc=$?
  printf '验证或日志写入失败:%s\n' "$rc" >&2
  exit "$rc"
fi

本轮重放了四段正文命令,正确材料通过;拒绝CA、错误名称和日志路径无法打开均阻止相应验收通过。脚本保留失败退出码,不因为日志文件存在就判成功。它只验离线链,还没有完成网络请求。

七、上线前按这张清单收口

  • 准确区分rejected与revoked,保存错误号、depth、subject及进程退出码。
  • 核对实际CA来源、全部相关条目、辅助信任属性与应用用途,不只比指纹。
  • 通过授权流程恢复信任材料,不删purpose、不清拒绝项、不关闭验证。
  • 恢复后验证名称、用途、完整链;再检查实际HTTPS终点、应用重载和业务响应。

实验仅使用临时目录做离线验证,证书与私钥已清理,未修改系统信任库、时钟或服务。未实测生产HTTPS、浏览器及3.x运行时。3.0官方文档用于解释信任锚规则,不把文档阅读冒充新版本实测。

八、参考资料

相关推荐
沫璃染墨1 小时前
从零入门计算机网络系列(五):UDP套接字编程实战——从核心API到客户端与服务器通信
linux·网络·c++·vscode·网络协议·udp
Margrop1 Margrop1 小时前
别再挨个试清华、中科大、阿里源了!国家队下场的“CERNET 镜像聚合站”,凭什么让你的下载直接起飞?
linux·开源镜像·cernet
一条破秋裤1 小时前
05_设备树自定义属性_写入读取验证
linux·网络·数据库
此生决int1 小时前
Linux系统(07)——进程概念(下)
linux·运维·服务器
迷途之人不知返1 小时前
【基础IO】-3-系统级别的文件操作
linux
下辈子不要当码农2 小时前
Linux驱动(2)
linux·运维·单片机
m0_587383002 小时前
碰碰好评卡功能落地实战 从需求梳理到上线部署全流程实操指南
java·linux·服务器·前端·javascript·vue.js·人工智能
筑梦之路2 小时前
Alibaba Cloud Linux 4 制作 Ansible RPM包实践(离线可复用)——筑梦之路
linux·运维·ansible
承渊政道2 小时前
Linux网络学习【应用层自定义协议与序列化实战:从手写序列化与反序列化到深入理解进程间关系与守护进程】
linux·网络·学习·ubuntu·json·序列化与反序列化