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

Rust中用openssl crate生成CMS签名无法通过OpenSSL终端验证问题

Rust生成CMS签名无法通过OpenSSL验证的问题

我是Rust新手,正在尝试为PNG文件生成CMS签名,使用的cargo openssl版本为"0.10.62"。编写的Rust代码如下:

use openssl::cms::{CmsContentInfo, CMSOptions};

use openssl::pkey::PKey;
use openssl::x509::X509;
use std::fs::{self};


fn main() {
    let certificate_contents = fs::read("files/certificate.pem").unwrap();
    let private_key_contents = fs::read("files/private_key.pem").unwrap();
    let image_contents = fs::read("files/image.png").unwrap();

    let signcert = X509::from_pem(&certificate_contents).unwrap();
    let pkey = PKey::private_key_from_pem(&private_key_contents).unwrap();
    
    let flags = CMSOptions::DETACHED;

    
    let cms = CmsContentInfo::sign(
      Some(&signcert),
      Some(&pkey),
      None, 
      Some(&image_contents),
      flags
    ).unwrap();


    fs::write("files/signature.pem", cms.to_pem().unwrap()).unwrap();
}

问题

生成的signature.pem无法通过终端的OpenSSL验证命令校验,验证命令如下:

openssl cms -verify -in signature.pem -inform PEM -content image.png -CAfile certificate.pem -out verified_content -noverify

而直接用终端OpenSSL命令生成的signature.pem可以正常验证,签名命令如下:

openssl cms -sign -in image.png -signer certificate.pem -inkey private_key.pem -outform PEM -out signature.pem -nodetach

终端使用的OpenSSL版本为:OpenSSL 3.1.4 24 Oct 2023 (Library: OpenSSL 3.1.4 24 Oct 2023)

问题原因及解决方法

核心差异在于签名的模式:

  • 终端命令使用-nodetach,生成的是非分离式CMS签名(签名文件中包含原始PNG内容)
  • Rust代码中设置了CMSOptions::DETACHED,生成的是分离式CMS签名(签名文件仅包含签名数据,不包含原始内容)

方案1:生成和终端命令一致的非分离式签名

修改代码中的flags为CMSOptions::empty(),去掉分离式标记:

let flags = CMSOptions::empty();

此时生成的签名会包含原始PNG内容,验证时无需指定-content image.png,可以用以下命令验证:

openssl cms -verify -in signature.pem -inform PEM -CAfile certificate.pem -out verified_content -noverify

方案2:修正分离式签名的生成逻辑

如果需要生成分离式签名,需将CmsContentInfo::sign的第四个参数(内容)设为None(根据openssl 0.10.62文档,当content为None时才会生成分离式签名):

let cms = CmsContentInfo::sign(
    Some(&signcert),
    Some(&pkey),
    None, 
    None, // 此处改为None
    flags
).unwrap();

修改后即可用你原来的验证命令正常校验。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 14:57:52