升级至OpenSSL 3后CMS_verify()返回“invalid digest”问题排查
问题原因
OpenSSL 3.0默认禁用了SHA-1这类被标记为弱算法的哈希函数,而你使用的fullsailor/pkcs7库在创建签名时,若未显式指定摘要算法,会默认用SHA-1生成CMS签名数据。这就导致OpenSSL 3.0验证时触发invalid digest错误——旧版本OpenSSL(1.0/1.1)对弱算法限制更宽松,所以能正常验证。
解决方案
方案一:修改Go服务器端代码(推荐)
在添加签名者时,显式指定强摘要算法(如SHA-256),替换默认的SHA-1:
signedData, err := pkcs7.NewSignedData(message) // 显式指定SHA-256作为摘要算法 config := pkcs7.SignerInfoConfig{ DigestAlgorithm: pkcs7.OIDDigestAlgorithmSHA256, } signedData.AddSigner(publicCert, privateKey, config) pem.Encode(out, &pem.Block{Type: "CMS", Bytes: sign})
重新生成签名后,OpenSSL 3.0即可正常验证。
方案二:临时调整OpenSSL 3.0配置(兼容旧签名)
如果无法修改服务器代码,可临时修改OpenSSL 3.0配置启用SHA-1:
- 编辑OpenSSL配置文件(通常为
/etc/pki/tls/openssl.cnf或/etc/openssl/openssl.cnf),添加legacy提供者配置:
[openssl_init] providers = provider_sect [provider_sect] default = default_sect legacy = legacy_sect [default_sect] activate = 1 [legacy_sect] activate = 1
- 执行验证命令时指定该配置:
openssl cms -verify -in message.pem -inform PEM -CAfile cacert.pem -config /path/to/modified/openssl.cnf
或通过环境变量临时生效:
export OPENSSL_CONF=/path/to/modified/openssl.cnf openssl cms -verify -in message.pem -inform PEM -CAfile cacert.pem
客户端C代码适配(兼容新旧签名)
如果要让C工具同时兼容旧SHA-1签名和新签名,可在OpenSSL 3.0环境中加载legacy提供者:
#include <openssl/provider.h> // 在初始化X509_STORE前加载legacy提供者 OSSL_PROVIDER_load(NULL, "legacy"); X509_STORE *st = X509_STORE_new(); X509 *cacert = rootcert(); /* 获取签名证书 */ X509_STORE_add_cert(st, cacert); CMS_ContentInfo *cms = PEM_read_bio_CMS(in, NULL, NULL, NULL); CMS_verify(cms, NULL, st, NULL, out, 0);
内容的提问来源于stack exchange,提问作者nafmo
相关产品推荐
相关产品推荐

