Статус: Новичок
Группы: Участники
Зарегистрирован: 24.03.2010(UTC) Сообщений: 4 Откуда: msk
Сказал(а) «Спасибо»: 1 раз
|
У меня есть данные, есть сертификат связанный с закрытым ключом - нужно сделать XMLподпись (для СМЭВ). С++ и CryptoAPI. Делаю канонизацию тэга, делаю хэш, записываю в DigestValue - значение правильно. Дальше нужно подписать полученный тэг <SignedInfo> Цитата:3.3. Элемент SignedInfo трансформируется в соответствии с алгоритмом «http://www.w3.org/2001/10/xml-exc-c14n#». Затем на основании полученной строки и ключа подписи формируется значение ЭП в соответствии с алгоритмом «http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411». Полученное значение ЭП кодируется в соответствии с алгоритмом «http://www.w3.org/2000/09/xmldsig#base64», символы не входящие в алфавит Base64 удаляются и полученное значение добавляется как дочерний текстовый узел к элементу SignatureValue. На входе канонизированный тэг <SignedInfo/>, как blob, length - его длина. Подпись кладется в sign. Сертификат с подходящими алгоритмами. Я делаю следующее: Код:bool
Hash_n_Sign::sign(void* blob, size_t length, std::string& sign)
{
// из бинарных данных делаю контекст сертификата
PCCERT_CONTEXT certContext;
certContext = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, (BYTE*)m_sSertificate.c_str(), m_sSertificate.length());
if (m_certContext)
{
HCRYPTPROV hCrypProv;
DWORD nKeyType;
BOOL bCallerFreeProv;
// получаю доступ к закрытому ключу
if (CryptAcquireCertificatePrivateKey(certContext, 0, NULL, &hCrypProv, &nKeyType, &bCallerFreeProv))
{
HCRYPTHASH hHashObject;
// Хэшируем данные
if (CryptCreateHash(hCrypProv, getHashAlgID(), NULL, NULL, &hHashObject))
{
if (CryptHashData(hHash, (BYTE*)blob, length, 0))
{
// Подписываем
DWORD dwSigLen = 0;
if (CryptSignHash(hHash, keyType, NULL, 0, NULL, &dwSigLen))
{
BYTE* pbSignature = 0;
if (pbSignature = (BYTE*)malloc(dwSigLen))
{
if (CryptSignHash(hHash, m_keyType, NULL, 0, pbSignature, &dwSigLen))
{
// кодирую в base64 и кладу в строку
InternalString hash64;
encode_base64((char*)pbSignature, dwSigLen, hash64, 0);
sign = narrow(hash64);
ret = true;
}
free(pbSignature);
}
}
}
CryptDestroyHash(hHash);
}
if (bCallerFreeProv)
CryptReleaseContext(hCrypProv, 0);
}
}
if (!ret)
{
DWORD err = GetLastError();
}
return ret;
}
Но что-то я здесь делаю не так и проверку на сайте смэв моя подпись не проходит. Взгляните незамыленным глазом, что я делаю не так.
|