如何使用 openssl 或任何其他在智能卡上签名的库创建 PKCS7 signedData 结构?

Posted

技术标签:

【中文标题】如何使用 openssl 或任何其他在智能卡上签名的库创建 PKCS7 signedData 结构?【英文标题】:how to create PKCS7 signedData structure with openssl or any other library with signing on smart card? 【发布时间】:2013-03-25 15:01:20 【问题描述】:

我需要创建 PKCS7 signedData 结构并在智能卡上执行签名。这几乎是 openssl 函数 PKCS7_sign 所做的,除了签名。也许有人可以为这个问题提供一些建议,即如何使用 openssl 或任何其他 c/c++ 跨平台库来做到这一点。 至于 openssl,PKCS7_sign 函数的标志 PKCS7_PARTIAL 或 PKCS7_STREAM 似乎很有用。如果我使用这些标志中的任何一个,我可以获得几乎完整的 PKCS7 结构。在这种情况下,结构是完整的,只是它不包含“数据”和“符号”。所以我只需要添加这些元素。但我没有找到如何做到这一点的方法。有人知道吗?

【问题讨论】:

不知道你是怎么处理智能卡的。 OpenSSL 唯一需要的是它的功能参数(证书、私钥和数据)。您必须从智能卡中提取证书和私钥并提供给 OpenSSL 功能。但是,如果您不能导出私钥,那就是一个问题。在我看来,保留这两个部分(在智能卡上和使用 OpenSSL 分开)。 无法从智能卡导出私钥。看起来这可能是一个奇怪的解决方法: - 生成公共指数 =1 的新 RSA 密钥对; - 使用 PKCS7_sing 函数和此密钥对创建 PKCS7 结构; - 使用 i2d_PKCS7_bio 获取生成的 PKCS7 结构。由于公共指数 =1,此结构包含准备 RSA 解密数据而不是符号; - 将此数据发送到智能卡进行解密并将其替换为结果。但这需要自己复制一些 openssl 函数,因为其中一个原始函数包含密钥检查。 即使无法导出私钥,也必须有某种方式使用该私钥对数据进行签名。为此,您可能需要修改 PKCS7_sign 的源代码以控制签名部分。在这里,您可以调用将使用智能卡对数据进行签名的函数,而不是使用 OpenSSL 签名。 @dbasic,谢谢。但问题是这不是微不足道的,至少对我来说是这样。 openssl PKCS7_sign 源代码中没有单独的函数用于签署 PKCS7 结构。取而代之的是,此操作分为一些功能,例如 PKCS7_dataInit 和 PKCS7_dataFinal,并且还使用了特殊类型的 BIO。 我正在解决同样的问题。到目前为止,我一直在尝试覆盖默认的签名方法(使用method = RSA_get_default_method,然后覆盖它的method->flags 和method->rsa_sign,用我的智能卡签名方法替换它)。请注意,您应该 method->flags |= RSA_METHOD_FLAG_NO_CHECK .. 我还在尝试,您是否设法解决了这个问题? 【参考方案1】:

您通常不希望(或在技术上被阻止)从智能卡中提取私钥。因为这是智能卡的关键——加密内存和连接的 CPU 的防篡改位,永远不会泄露您的私钥。

因此,您需要很好地要求芯片卡为您签名。

OpenSSL 可以做到这一点——但需要知道如何与芯片卡通信。这通常是通过“引擎”完成的。最常见的是 #15 的 pkcs#11 用于此 - 与供应商芯片卡(阅读器)驱动程序结合使用。

然后您通常需要获取插槽和密钥标识符:

# Extracting slot, auth ids and key id's for later use/reference
#
set `pkcs11-tool --module /usr/lib/opensc-pkcs11.so --list-slots | grep Slot | grep SCM`
SLOT=$2
set `pkcs15-tool --list-keys | grep ID`
AID=$4
KID=$7

之后你可以在卡片上做“事情”:

/usr/bin/openssl << EOM
engine dynamic -pre SO_PATH:/Library/OpenSC/lib/engines/engine_pkcs11.so  -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:opensc-pkcs11.so
XXX -engine pkcs11 -b-key slot_$SLOT-id_$KID -keyform engine  ....
EOM

这样的事情之一就是签署 pkcs7。从代码 - 几乎做同样的事情。我通常使用 openssl 它的应用程序目录中的 app/util 便利 stuf 来简化生活。

【讨论】:

以上是关于如何使用 openssl 或任何其他在智能卡上签名的库创建 PKCS7 signedData 结构?的主要内容,如果未能解决你的问题,请参考以下文章

Java applet使用智能卡实现数字签名

使用 openssl 对文件进行数字签名

在 C++ 中使用智能卡创建证书签名请求

我们如何在 C++ 和 windows API 中验证 openssl 数字签名

使用 HMAC 或 OpenSSL 进行 URL 签名

OpenSSL生成HTTPS自签名证书