如何使用javascript创建签名PKCS#7消息?

如何使用javascript创建签名PKCS#7消息?,javascript,cryptography,pkcs#7,certenroll,Javascript,Cryptography,Pkcs#7,Certenroll,我正在尝试使用javascript在客户端为PKCS#10认证请求创建签名PKCS#7消息 PKCS#10上有一些很好的例子: 但我需要创建PKCS#7,却不知道如何实现。CertEnroll的官方文档中缺少示例(实际上根本没有): 我最终得到了以下代码: var XCN\u CRYPT\u STRING\u BASE64REQUESTHEADER=3; var XCN\u CERT\u NAME\u STR\u NONE=0; var_certEnrollmentClassFactory=新的

我正在尝试使用javascript在客户端为PKCS#10认证请求创建签名PKCS#7消息

PKCS#10上有一些很好的例子:

但我需要创建PKCS#7,却不知道如何实现。CertEnroll的官方文档中缺少示例(实际上根本没有):

我最终得到了以下代码:

var XCN\u CRYPT\u STRING\u BASE64REQUESTHEADER=3;
var XCN\u CERT\u NAME\u STR\u NONE=0;
var_certEnrollmentClassFactory=新的ActiveXObject(“X509Enrollment.CX509EnrollmentWebClassFactory”);
ComposePKCS10Request:函数(容器名称、主题)
{
//PKCS#10证书申请
var objRequest=_certEnrollClassFactory.CreateObject(“X509Enrollment.CX509CertificateRequestKCS10”);
var objCSP=objCertEnrollClassFactory.CreateObject(“X509Enrollment.CCspInformation”);
var objCSPs=objCertEnrollClassFactory.CreateObject(“X509Enrollment.CCspInformations”);
//使用所需的加密服务提供程序(csp)初始化csp对象
objCSP.InitializeFromName(“Microsoft增强加密提供程序v1.0”);
//将此CSP对象添加到CSP集合对象
objCSP.Add(objCSP);
//可用于加密、签名和密钥协商的非对称私钥。
var objPrivateKey=_certEnrollClassFactory.CreateObject(“X509Enrollment.CX509PrivateKey”);
//为私钥对象提供密钥容器名称、密钥长度和密钥规范
objPrivateKey.ContainerName=ContainerName;
//objPrivateKey.Length=1024;
objPrivateKey.KeySpec=1;//AT_KEYEXCHANGE=1
//提供CSP集合对象(在本例中仅包含1个CSP对象)
//到私钥对象
objPrivateKey.CspInformations=objCSPs;
//基于私钥初始化P10
objRequest.InitializeFromPrivateKey(1,objPrivateKey,“”;//上下文用户=1
//X.500可分辨名称(DN)
//DN由一系列相对可分辨名称(RDN)组成。每个RDN由一组属性组成,
//每个属性都由一个对象标识符(OID)和一个值组成
//通过DirectoryString结构。
var objDn=_certEnrollClassFactory.CreateObject(“X509Enrollment.CX500DistrictedName”);
//DN相关材料
objDn.Encode(主题,XCN\u证书名称\u STR\u无);
objRequest.Subject=objDn;
返回objRequest;
}
CreatePKCS7:函数(容器名称,主题)
{
//PKCS#7证书申请
var objPKCS7Request=_certEnrollClassFactory.CreateObject(“X509Enrollment.CX509CertificateRequestsPKCS7”);
//通过PKCS#10证书请求初始化PKCS#7证书请求
objPKCS7Request.initializeFrominerRequest(这个.ComposePKCS10Request(containerName,subject));
var objSignerCert=_certEnrollClassFactory.CreateObject(“X509Enrollment.CSignerCertificate”);
var verifyType=4;/*VerifyAllowUI,请参阅typedef枚举X509PrivateKeyVerify*/
var encodingType=0x3;/*请参阅typedef enum encodingType*/
/**********************************************************************/
/*我必须在这里提供证书???我如何从UI获得它*/
/**********************************************************************/
var strCertificate=';
objSignerCert.Initialize(false、verifyType、encodingType、strecertificate);
/*****************************************************************************/
/*我也不是舒尔,签名证书可以通过javascript访问*/
/*****************************************************************************/
objPKCS7Request.SignerCertificate=objSignerCert;
//表示顶级对象,使您能够在证书层次结构中注册并安装证书响应
var objEnroll=_certEnrollClassFactory.CreateObject(“X509Enrollment.CX509Enrollment”);
//报名
objEnroll.InitializeFromRequest(objPKCS7Request);
var-pkcs7;
尝试
{
pkcs7=objEnroll.CreateRequest(XCN\u CRYPT\u STRING\u BASE64REQUESTHEADER);
}
捕获(e)
{
...
}
返回pkcs7;
}
有没有办法用javascript创建PKCS#7消息

更新:我已经收到PKCS#10证书请求(请参阅代码示例中的第一个函数),需要为其创建PKCS#7签名消息。好的,我解释一下我的问题。如何使用javascript创建签名PKCS#7消息?(理想情况下,它应该允许使用UI指定适当的证书。)


至于javascript,我知道这不是一种方便的方法,但很合适,因为我必须在客户端(在浏览器中)处理它。此外,cert enroll IX509CertificateRequestTpkcs7接口具有标记为[WebEnabled]的方法,因此我相信一定有办法完成我所述的操作。

VBScript方法(它将提示选择证书):

功能标志消息(消息)
昏厥
Set oUtils=CreateObject(“CAPICOM.Utilities”)
暗cpcSigner
设置cpcSigner=CreateObject(“CAPICOM.Signer”)
cpcSigner.Options=2'CAPICOM\u证书\u仅包括\u结束\u实体\u
Dim cpcSignedData
设置cpcSignedData=CreateObject(“CAPICOM.SignedData”)
cpcSignedData.Content=oUtils.base64解码(消息)
SignMessage=cpcSignedData.Sign(cpcSigner,False)
端函数
Javascript方法(由于在JS中对字符串进行编码,您将获得损坏的签名,因此我建议使用VBScript对客户端脚本中的数据进行签名,因为它可以与JS进行互操作):

var CAPICOM\u证书\u包含\u结束\u实体\u仅=2;
SignMessage:函数(消息){
var cpcSigner=新的ActiveXObject(“CAPICOM.Signer”);
cpcSigner.Options=CAPICOM\u CERTIFICATE\u INCLUDE\u END\u ENTITY\u;
var cpcSignedData=新的ActiveXObject(“CAPICOM.SignedData”);
var oUtils=新的ActiveXObject(“CAPICOM.Utilities”);
cpcSign
ContentInfo ::= SEQUENCE {
  contentType ContentType,
  content
    [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }

ContentType ::= OBJECT IDENTIFIER
data OBJECT IDENTIFIER ::= { pkcs-7 1 }
signedData OBJECT IDENTIFIER ::= { pkcs-7 2 }
envelopedData OBJECT IDENTIFIER ::= { pkcs-7 3 }
signedAndEnvelopedData OBJECT IDENTIFIER ::= { pkcs-7 4 }
digestedData OBJECT IDENTIFIER ::= { pkcs-7 5 }
encryptedData OBJECT IDENTIFIER ::= { pkcs-7 6 }
pkcs-7 OBJECT IDENTIFIER ::=
  { iso(1) member-body(2) US(840) rsadsi(113549)
      pkcs(1) 7 }
var PKCS7_CONTENT_TYPES = {
    "1 2 840 113549 1 7 1": "data",
    "1 2 840 113549 1 7 2": "signedData",
    "1 2 840 113549 1 7 3": "envelopedData",
    "1 2 840 113549 1 7 4": "signedAndEnvelopedData",
    "1 2 840 113549 1 7 5": "digestData",
    "1 2 840 113549 1 7 6": "encryptedData",
};

var ContentInfo = asn1.define('ContentInfo', function() {
    this.seq().obj(
        this.key('contentType').objid(PKCS7_CONTENT_TYPES),
        this.key('content').optional().explicit(0).any()
    );
});
var signedData = ...
   contentInfoEncoded = ContentInfo.encode({
     'contentType': 'signedData',
     'content': signedData
   })