Я переношу 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 ???