Openssl CSR签名是如何工作的?

Openssl CSR签名是如何工作的?,openssl,x509,Openssl,X509,我正在尝试使用OpenSSL API对文件进行签名 我无法使用X509\u sign()方法,因为我需要使用第三方API对请求进行签名。此API要求我的应用程序发送需要签名的数据,并将返回签名 我需要发送char*以向第三方API签名,但我不了解签名过程是如何工作的: 我是否需要仅使用CSR中的数据来构造此char*,例如公钥的主题、指数和模数: Char*=“DN=test,O=something…123456(这是指数)a2:43:65(这是模数). 或者,我是否需要使用OpenSSL中的

我正在尝试使用OpenSSL API对文件进行签名

我无法使用
X509\u sign()
方法,因为我需要使用第三方API对请求进行签名。此API要求我的应用程序发送需要签名的数据,并将返回签名

我需要发送
char*
以向第三方API签名,但我不了解签名过程是如何工作的:

  • 我是否需要仅使用CSR中的数据来构造此
    char*
    ,例如公钥的主题、指数和模数:

    Char*=“DN=test,O=something…123456(这是指数)a2:43:65(这是模数).

  • 或者,我是否需要使用OpenSSL中的
    -text
    命令生成包含所有元素的缓冲区:

    证书:
    数据:
    主题:dn=测试,O=某物
    公钥信息:
    指数:123456
    模数:
    A2:43:65
    ..


总结:CA在执行X509证书签名时实际使用了请求的哪些元素,以及该数据应以何种格式显示?

您的标题和正文不一致;openssl
X509\u sign()
签署证书,而不是CSR。CSR不是证书,证书不是CSR,颁发证书也不是像许多无知或懒惰的人所说的那样“签署CSR”。(正常)CSR实际上是由请求者签署的,而不是CA。openssl对CSR使用类型
X509_-REQ
,并
X509_-REQ-sign
签署CSR

但答案基本相同。X.509证书或PKCS#10 CSR是由三件事组成的序列:一个包含要签名的数据的主体、一个
算法标识符和签名(作为位字符串)。这些是使用可分辨编码规则或DER定义和编码的。通过
openssl req-text
openssl x509-text
或其他程序输入或显示的文本表单表示相同的数据,但通常不足以再现精确的位,并且您必须具有数字签名的精确位重新开始工作。(这就是DER中“Districted”的意思;它通过指定用于某些其他不明确情况的精确八位字节和位来修改基本编码规则或BER。)对于CSR,请参阅中的我的答案;对于cert,“wrapper”是相同的,但主体明显不同,并且包含的内容比DN和publickey多得多

TL;DR对于
X509*cert
您签署了
cert->cert\u info
的DER编码,其类型为
X509\u CINF
,可以使用
i2d\u X509\u CINF()进行编码
。对于
X509\u REQ*csr
您使用
i2d\u X509\u REQ\u info()
使用类型
X509\u REQ\u info
csr->REQ\u info
的DER编码进行签名

备选方案:openssl具有引擎的概念,它是一个外部库和/或硬件单元,用于处理一些加密操作。如果您的第三方API是或可以“包装”为openssl引擎,则您可以通过配置和指定该引擎来使用(几乎所有)正常的openssl例程。
如果这个引擎还不存在,那么仅仅为了你的项目去做可能会有太多的工作,但是如果你预见到其他(未来)的事情使用它可能是值得的。

您需要查看第三方API的文档,看看它需要什么输入格式。也许它需要一些标准格式,也许不需要。根据您提供的信息,我们可以告诉您该字符串中必须显示什么信息,但不需要如何格式化。谢谢,这对我很有用,但我不知道如何将此签名设置到我的X509证书中…您知道如何设置吗?如果要使用OpenSSL,请将->sig_alg更改为&X509_ALGOR,其中包含在*cert_info->签名处的值的副本,该值在签名之前必须是正确的,->signature to为&ASN1_BIT_字符串,其中包含“wire”签名值(对于RSA,仅为双字节数,对于DSA或ECDSA,为两个整数序列的DER编码)。遵循OpenSSL规则,在这种类型的结构中设置的任何指针都指向使用OpenSSL_malloc中的xxx_新内存或唯一内存创建的唯一对象,以及任何杀死您的指针xxx_free或OpenSSL_free,如果适用……。然后您可以使用uisual i2d_X509[\u fp}\u bio]或PEM_write对生成的X509*进行编码和/或写入[\u bio]\u X509,display witch X509\u print等。或者,将您已经拥有的主体的DER编码(用于签名),“签名”algid的DER编码从主体中取出,以及包含规范签名的位字符串的DER/BER编码,然后加入DER/BER序列。(不要忘记位字符串中未使用的位八位组。)如果你想要PEM,那么以标准方式将DER转换为PEM,即base64+中断+开始/结束行。非常感谢dave,这非常有帮助。在我的第一种方法中,我忘记了在cert\u信息部分添加X509算法的副本,我的签名是错误的。最后一个问题,我不完全理解你的意思:and->signature to be&ASN1\BI包含“wire”签名值的T_字符串(对于RSA,仅为bigendian字节的数字,对于DSA或ECDSA,为两个整数的序列编码)。因为我要将签名放入X509对象中的操作是:证书->签名->数据=新的无符号字符[signatureLenght];memcpy(证书->签名->数据、签名、签名长度);证书->签名->长度=签名长度;