3

JavaScript を使用して、クライアント側で PKCS#10 証明書要求用の署名付き PKCS#7 メッセージを作成しようとしています。

PKCS#10 には良い例があります: http://blogs.msdn.com/b/alejacma/archive/2009/01/28/how-to-create-a-certificate-request-with-certenroll-javascript.aspx

しかし、PKCS#7 を作成する必要があり、その方法がわかりません。CertEnroll の公式ドキュメントには例がありません (実際にはまったくありません): http://msdn.microsoft.com/en-us/library/windows/desktop/aa374850(v=vs.85).aspx

私はこのコードで終わった:

var XCN_CRYPT_STRING_BASE64REQUESTHEADER = 3;

var XCN_CERT_NAME_STR_NONE = 0;

var _certEnrollClassFactory = new ActiveXObject("X509Enrollment.CX509EnrollmentWebClassFactory");


ComposePKCS10Request: function (containerName, subject)
{
    // PKCS #10 certificate request
    var objRequest = _certEnrollClassFactory.CreateObject("X509Enrollment.CX509CertificateRequestPkcs10");

    var objCSP = objCertEnrollClassFactory.CreateObject("X509Enrollment.CCspInformation");
    var objCSPs = objCertEnrollClassFactory.CreateObject("X509Enrollment.CCspInformations");

    //  Initialize the csp object using the desired Cryptograhic Service Provider (CSP)
    objCSP.InitializeFromName("Microsoft Enhanced Cryptographic Provider v1.0");

    //  Add this CSP object to the CSP collection object
    objCSPs.Add(objCSP);

    // asymmetric private key that can be used for encryption, signing, and key agreement.
    var objPrivateKey = _certEnrollClassFactory.CreateObject("X509Enrollment.CX509PrivateKey");

    //  Provide key container name, key length and key spec to the private key object
    objPrivateKey.ContainerName = containerName;
    //objPrivateKey.Length = 1024;
    objPrivateKey.KeySpec = 1; // AT_KEYEXCHANGE = 1

    //  Provide the CSP collection object (in this case containing only 1 CSP object)
    //  to the private key object
    objPrivateKey.CspInformations = objCSPs;

    // Initialize P10 based on private key
    objRequest.InitializeFromPrivateKey(1, objPrivateKey, ""); // context user = 1

    // X.500 distinguished name (DN)
    // The DN consists of a sequence of relative distinguished names (RDNs). Each RDN consists of a set of attributes, 
    // and each attribute consists of an object identifier (OID) and a value. The data type of the value is identified 
    // by the DirectoryString structure.
    var objDn = _certEnrollClassFactory.CreateObject("X509Enrollment.CX500DistinguishedName");

    // DN related stuff
    objDn.Encode(subject, XCN_CERT_NAME_STR_NONE);
    objRequest.Subject = objDn;

    return objRequest;
}

CreatePKCS7: function (containerName, subject)
{
    // PKCS #7 certificate request
    var objPKCS7Request = _certEnrollClassFactory.CreateObject("X509Enrollment.CX509CertificateRequestPkcs7");

    // initialize PKCS #7 certificate request by PKCS #10 certificate request
    objPKCS7Request.InitializeFromInnerRequest(this.ComposePKCS10Request(containerName, subject));

    var objSignerCert = _certEnrollClassFactory.CreateObject("X509Enrollment.CSignerCertificate");
    var verifyType = 4; /* VerifyAllowUI, see typedef enum X509PrivateKeyVerify */
    var encodingType = 0x3; /* see typedef enum EncodingType */

    /**********************************************************************/
    /* I have to provide certificate here??? How can I obtain it from UI? */
    /**********************************************************************/
    var strCertificate = '?????????????????????';

    objSignerCert.Initialize(false, verifyType, encodingType, strCertificate);

    /*****************************************************************************/
    /* Also I'm not shure that SignerCertificate can be accessed via javascript. */
    /*****************************************************************************/
    objPKCS7Request.SignerCertificate = objSignerCert;

    // represents the top level object and enables you to enroll in a certificate hierarchy and install a certificate response
    var objEnroll = _certEnrollClassFactory.CreateObject("X509Enrollment.CX509Enrollment");

    // Enroll
    objEnroll.InitializeFromRequest(objPKCS7Request);

    var pkcs7;

    try
    {
        pkcs7 = objEnroll.CreateRequest(XCN_CRYPT_STRING_BASE64REQUESTHEADER);
    }
    catch (e)
    {
        ...
    }

    return pkcs7;
}

javascript で PKCS#7 メッセージを作成する方法はありますか?

更新: 既に PKCS#10 証明書要求があり (コード サンプルの最初の関数を参照)、そのために PKCS#7 署名付きメッセージを作成する必要があります。わかりました、私は私の質問を言い換えます。javascriptで署名付きPKCS#7メッセージを作成するには? (理想的には、UI で適切な証明書を指定できるようにする必要があります。)

JavaScriptについては、便利な方法ではないことは理解していますが、クライアント側(ブラウザ)で処理する必要があるため適切です。さらに、証明書登録 IX509CertificateRequestPkcs7 インターフェイスには [WebEnabled] とマークされたメソッドがあるため、私が述べたことを実行する方法があるに違いないと思います。

4

3 に答える 3

3

Forge を使用して純粋な JS で PKCS#7 と PKCS#10 を実行できます (ブラウザまたは node.js で動作します)。

https://github.com/digitalbazaar/forge#pkcs7

https://github.com/digitalbazaar/forge#pkcs10

于 2013-07-12T01:24:47.900 に答える
0

VBScript メソッド(証明書を選択するように求められます):

Function SignMessage(Message)
    Dim oUtils
    Set oUtils = CreateObject("CAPICOM.Utilities")
    Dim cpcSigner
    Set cpcSigner = CreateObject("CAPICOM.Signer")
    cpcSigner.Options = 2 'CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY
    Dim cpcSignedData
    Set cpcSignedData = CreateObject("CAPICOM.SignedData")
    cpcSignedData.Content = oUtils.Base64Decode(Message)
    SignMessage = cpcSignedData.Sign(cpcSigner, False)
End function

JavascriptメソッドJSで文字列をエンコードすると署名が破損するため注意してください。JSと相互運用できるため、クライアントスクリプトでデータに署名するためにVBScriptを使用することをお勧めします):

var CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY = 2;

SignMessage: function (message) {
    var cpcSigner = new ActiveXObject("CAPICOM.Signer");
    cpcSigner.Options = CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY;

    var cpcSignedData = new ActiveXObject("CAPICOM.SignedData");
    var oUtils = new ActiveXObject("CAPICOM.Utilities");
    cpcSignedData.Content = oUtils.Base64Decode(message);

    return cpcSignedData.Sign(cpcSigner, false);
}
于 2013-04-25T09:50:02.880 に答える