Проблема преобразования этого кода для подписи и шифрования запросов мыла из .NET в узел - PullRequest
0 голосов
/ 19 сентября 2019

Я переношу API-интерфейс, который использует сторонние мыльные сервисы, сделанные на C #, на Node.JS.Есть определенный сервис, с которым у меня проблемы.Мне удалось подключиться к службе, отправить аргументы, которые ожидали правильно, и получить ответ.Однако у меня должна быть какая-то ошибка в подписи / шифровании запроса.Поскольку я получаю ответ в виде xml со следующим описанием ошибки: « Недопустимый тип криптографического сообщения ».Следует уточнить, что в .NET я использую сертификат .pfx, а в Node.JS мне пришлось преобразовать его в .pem, выполнив следующую команду openssl: openssl pkcs12 -in cert.pfx -clcerts -nokeys -из cert.pem .И ввод пароля сертификата по запросу openssl.

Без дальнейшего введения я покажу вам код, который я хочу перенести:

        string strXmlRequest = "some string in xml format";
        this.SignMessage(strXmlRequest);
        string strBase64Request = this.EncodeMessage(strXmlRequest);

public void SignMessage(string message)
        {
            signedMessage = Encoding.ASCII.GetBytes(message);

            SignedCms = new SignedCms(new ContentInfo(signedMessage));
            CmsSigner.Certificate = Certificate;
            CmsSigner.IncludeOption = X509IncludeOption.EndCertOnly;
            try
            {
                SignedCms.ComputeSignature(CmsSigner, false);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public string EncodeMessage(string message)
        {
            string base64Message = "-----BEGIN PKCS7-----\r\n";
            base64Message += Convert.ToBase64String(SignedCms.Encode(), Base64FormattingOptions.InsertLineBreaks);
            base64Message += "\r\n-----END PKCS7-----\r\n";
            return base64Message;
        }

И это то, что я пытался использовать библиотеку node-forge:

public signAndEncodeMessageNodeForge(message: string): string {
    // create cert object
    const pem = fs.readFileSync(path.join(__dirname, '../../resources/cert.pem'), 'utf8');
    const cert = forge.pki.certificateFromPem(pem);

    // create signed data for sign
    let pk7 = forge.pkcs7.createSignedData();
    // add certificate
    pk7.addCertificate(cert);
    // set content
    pk7.content = forge.util.createBuffer();
    pk7.content.putString(message);
    // sign
    pk7.sign();

    // create envelop data for encrypt
    let p7 = forge.pkcs7.createEnvelopedData();
    p7.addRecipient(cert);
    // set content
    p7.content = forge.util.createBuffer(pk7.content.data);
    // encrypt
    p7.encrypt();

    // obtain encrypted data with DER format
    const ContentBytes = forge.asn1.toDer(p7.toAsn1()).getBytes();

    let base64Message = '-----BEGIN PKCS7-----\r\n';
    base64Message += Buffer.from(ContentBytes, 'binary').toString('base64');
    base64Message += '\r\n-----END PKCS7-----\r\n';
    return base64Message;
}

Пояснение: я уже проверил, используя API .NET (который работает правильно), что XML-файл, который я хочу подписать / зашифровать, находится в ожидаемом формате, и я также проверил, что запрос службыпроводится правильно.Ошибка из-за чего-то, что я делаю неправильно в подписанном / зашифрованном

ОБНОВЛЕНИИ:

Мне удалось успешно получить ответ, который я ожидал от службывнося следующие изменения в код:

 public signAndEncodeMessage(message: string): string {

        // create cert object
        const pem = fs.readFileSync(path.join(__dirname, '../resources/cert.pem'), 'utf8');
        const cert = forge.pki.certificateFromPem(pem);

        // create private key
        const pkpem = fs.readFileSync(path.join(__dirname, '../resources/privkey.pem'), 'utf8');
        const privkey = forge.pki.decryptRsaPrivateKey(pkpem, 'cert_password');

        let pk7 = forge.pkcs7.createSignedData();
        pk7.content = forge.util.createBuffer(message, 'ascii');
        pk7.addCertificate(cert);
        pk7.addSigner({
            key: privkey,
            certificate: cert,
            digestAlgorithm: forge.pki.oids.sha256,
            authenticatedAttributes: [{
                type: forge.pki.oids.contentType,
                value: forge.pki.oids.data,
            }, {
                type: forge.pki.oids.messageDigest,
            }, {
                type: forge.pki.oids.signingTime,
                value: new Date(),
            }],
        });
        pk7.sign();

        return forge.pkcs7.messageToPem(pk7);
    }

В основном теперь я просто подписываю, а не подписываю и шифрую.И я добавил подписавшего.

Однако мне интересно, правильно ли я перенес код, ведь служба корректно реагирует.Я делаю так же, как в .NET ???

...