| ||||
| ||||
Вот исходники к моему последнему вопросу, создание подписи, ф-ия класса. int CSignature::CreateSignature() { if (!m_pSignedData || ! m_pSignedData[0]) return CL_NOT_INITIALIZED; // Для создания подписи используем ф-ию CryptSignMessage(..) // а не CryptSignHash(..) и остальные низкоуровневые... // ибо нам нужна подпись в формате PKSC#7 формате CString sLastError ="success"; int iLastError =CL_SUCCESS; // Переменные для указателя на данные и их длины BYTE *pbSignedBuffer = NULL; DWORD dwSignedDataLen = 0; // Переменные для указателя на результат подписи и её длины BYTE * pbBinSignatureValue =NULL; DWORD dwBinSignatureValueLen =0; // Переменные для парметров ф-ии ryptSignMessage DWORD MessageSizeArray[1]; const BYTE *MessageArray[1]; // Сертификат (PCCERT_CONTEXT) PCCERT_CONTEXT pCert = NULL; // Используем из файла для инициализации контекста pCert =m_pCertificate->GetCertContext(); // Получаем сертификат // идентификатор алгоритма хеширования (для госта 94 и 2001 используется оди и тот же) char OID[64] =szOID_CP_GOST_R3411; m_pSignedData ="test_test_test"; pbSignedBuffer = (BYTE*)m_pSignedData; dwSignedDataLen = (DWORD)(strlen(m_pSignedData)+1); // Создаем и заполняем структуру для создания ц.п. CRYPT_SIGN_MESSAGE_PARA SignParams; // Обязательно нужно обнулить все поля структуры. // Иначе это может привести к access violation в функциях CryptoAPI // В примере из MSDN это отсутствует memset(&SignParams, 0, sizeof(CRYPT_SIGN_MESSAGE_PARA)); SignParams.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA); SignParams.dwMsgEncodingType = ENCODING_TYPE; //(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) SignParams.pSigningCert = pCert; SignParams.HashAlgorithm.pszObjId = OID; SignParams.HashAlgorithm.Parameters.cbData = 0; SignParams.HashAlgorithm.Parameters.pbData = NULL; SignParams.pvHashAuxInfo = NULL; // не используется SignParams.cMsgCert = 0; // не включаем сертификат отправителя SignParams.rgpMsgCert = NULL; SignParams.cAuthAttr = 0; SignParams.dwInnerContentType = 0; SignParams.cMsgCrl = 0; SignParams.rgAuthAttr = 0; MessageArray[0] = pbSignedBuffer; MessageSizeArray[0] =dwSignedDataLen; // Получаем длину буфера подписи if(!CryptSignMessage( &SignParams, // указатель на SigParams TRUE, // подпись создается отдельно 1, // число сообщений MessageArray, // сообщение MessageSizeArray, // длина сообщения NULL, // буфер для подписи &dwBinSignatureValueLen)) // размер буфера { sLastError.Format("Error %x during CryptBinaryToString.", ::GetLastError()); iLastError = CL_CRYPTOAPI_ERROR; return iLastError; } // выделяем память под подпись pbBinSignatureValue = new BYTE[dwBinSignatureValueLen]; // формируем подпись if(!CryptSignMessage( &SignParams, // указатель на SigParams TRUE, // подпись создается отдельно 1, // число сообщений MessageArray, // сообщение MessageSizeArray, // длина сообщения pbBinSignatureValue, // буфер для подписи &dwBinSignatureValueLen)) // размер буфера { sLastError.Format("Error %x during CryptBinaryToString.", ::GetLastError()); iLastError = CL_CRYPTOAPI_ERROR; return iLastError; } char * pBASE64SignatureValue =NULL; DWORD dwBASE64SignatureValueLen =0; //Переводим в BASE64 if(!CryptBinaryToString(pbBinSignatureValue, dwBinSignatureValueLen, CRYPT_STRING_BASE64, NULL, & dwBASE64SignatureValueLen)) { sLastError.Format("Error %x during CryptBinaryToString.", ::GetLastError()); iLastError = CL_CRYPTOAPI_ERROR; return iLastError; } pBASE64SignatureValue =new char [(int)dwBASE64SignatureValueLen+1]; if(!CryptBinaryToString(pbBinSignatureValue, dwBinSignatureValueLen, CRYPT_STRING_BASE64, pBASE64SignatureValue, & dwBASE64SignatureValueLen)) { sLastError.Format("Error %x during CryptBinaryToString.", ::GetLastError()); iLastError = CL_CRYPTOAPI_ERROR; return iLastError; } pBASE64SignatureValue[dwBASE64SignatureValueLen]=0; //присваиваем адрес значения подписи в BASE64 формате переменной класса m_pSignedValue= pBASE64SignatureValue; return iLastError; } | ||||
Ответы: | ||||
| ||||
А есть сертификат и результат работы? | ||||
| ||||
Да есть вот полученная полпись: MIIBBwYJKoZIhvcNAQcCoIH5MIH2AgEBMQwwCgYGKoUDAgIJBQAwCwYJKoZIhvcN AQcBMYHVMIHSAgEBMHMwZTEgMB4GCSqGSIb3DQEJARYRaW5mb0BjcnlwdG9wcm8u cnUxCzAJBgNVBAYTAlJVMRMwEQYDVQQKEwpDUllQVE8tUFJPMR8wHQYDVQQDExZU ZXN0IENlbnRlciBDUllQVE8tUFJPAgpuNK3NAAEAABDHMAoGBiqFAwICCQUAMAoG BiqFAwICEwUABEAT0dLHVOkpGrAV8/3b9FcNdk10BH8k44BoTKuSQLW/+hlHHfgi Wi8vMY4ROhWBxq0/5bG17af9ZwYKpoic1GnK Вот сертификат: MIIDkjCCAz+gAwIBAgIKbjStzQABAAAQxzAKBgYqhQMCAgMFADBlMSAwHgYJKoZI hvcNAQkBFhFpbmZvQGNyeXB0b3Byby5ydTELMAkGA1UEBhMCUlUxEzARBgNVBAoT CkNSWVBUTy1QUk8xHzAdBgNVBAMTFlRlc3QgQ2VudGVyIENSWVBUTy1QUk8wHhcN MDYwNzA3MTMwNzAxWhcNMDcwNzA3MTMxNzAxWjCBqzELMAkGA1UEBhMCUlUxJjAk BgNVBAcMHdCh0LDQvdC60YIt0J/QtdGC0LXRgNCx0YPRgNCzMRMwEQYDVQQKEwpz aWdtYS1zb2Z0MSgwJgYDVQQLDB/QntGC0LTQtdC7INGA0LDQt9GA0LDQsdC+0YLQ utC4MQ8wDQYDVQQDEwZBbmRyZXkxJDAiBgkqhkiG9w0BCQEWFXBhbkBzaWdtYS1z b2Z0LnNwYi5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiQABgcqhQMCAh4BA0MABEA/ lU04KDrGpg4XiRn9NQubdJp2JKyfGOP0u2eTt6qMCv1K6fSBRmBZiO7sWmUEdDS7 Zd/Wf39qDjjQudPsbN7Mo4IBhDCCAYAwDgYDVR0PAQH/BAQDAgTwMBkGCSqGSIb3 DQEJDwQMMAowCAYGKoUDAgIVMB0GA1UdDgQWBBTAVxM58CF18a/g/LyRsxfcraBx +jATBgNVHSUEDDAKBggrBgEFBQcDAjAfBgNVHSMEGDAWgBRIVTAYyzwiqRfXYmJk BaekzIaKETBSBgNVHR8ESzBJMEegRaBDhkFodHRwOi8vd3d3LmNyeXB0b3Byby5y dS9jZXJ0ZW5yb2xsL1Rlc3QlMjBDZW50ZXIlMjBDUllQVE8tUFJPLmNybDCBqQYI KwYBBQUHAQEEgZwwgZkwZAYIKwYBBQUHMAKGWGh0dHA6Ly93d3cuY3J5cHRvcHJv LnJ1L0NlcnRFbnJvbGwvQ3J5cHRvLmNyeXB0b3Byby5ydV9UZXN0JTIwQ2VudGVy JTIwQ1JZUFRPLVBSTygxKS5jcnQwMQYIKwYBBQUHMAGGJWh0dHA6Ly93d3cuY3J5 cHRvcHJvLnJ1L29jc3Avb2NzcC5zcmYwCgYGKoUDAgIDBQADQQC3m2wUqK0aiXyK f0kjGrfB3Zq4EUc3rQ7x4yytxl0gjn4rPri4RDGSCG8S3KkeVYajdNe/lQo945Kt mOs6PJMz Вот строку, что подписываем, хотя это в исходниках есть: test_test_test ил Ваи надо все архивом на мыло скинуть??? | ||||
| ||||
вот шаблон при создании и проверке csptest-ом csptest.exe -sfsign -in input.txt -out output.txt -my "test" -sign -detached -base64 csptest.exe -sfsign -in input.txt -my "test" -detached -verify -signature output.txt -base64 опять же могу прислать сертификат, полученную подпись, и подписываемое сообщение в файлах на ваше мыло, исходники Вы видели, ума не приложу в чем может быть проблема.... | ||||
| ||||
Как вообще может быть чтобы я сам что подписываю, удачно проверяю а csptest на том же сертификате, подписью и подписываемом сообщении говорит что подпись неверная???? | ||||
| ||||
Не, на форуме нормально... У меня проверяет все, csptest выдает CSP (Type:71) v3.0.3293 KC1 Release OS:Windows CPU:IA32 FastCode:READY,ENABLED. CSP (Type:75) v3.0.3293 KC1 Release OS:Windows CPU:IA32 FastCode:READY,ENABLED. #0: pan@sigma-soft.spb.ru, Andrey, ╬Єфхы ЁрчЁрсюЄъш, sigma-soft, ╤рэъЄ-╧хЄхЁсєЁу , RU Valid from 07.07.2006 to 07.07.2007 #0: pan@sigma-soft.spb.ru, Andrey, ╬Єфхы ЁрчЁрсюЄъш, sigma-soft, ╤рэъЄ-╧хЄхЁсєЁу , RU Valid from 07.07.2006 to 07.07.2007 Detached Signature was verified OK Total: SYS: 0.141 sec USR: 0.094 sec UTC: 0.250 sec [ErrorCode: 0x00000000] Вы код подписи привели, он правильный... А код записи исходного сообщения в файл нет. Вы же когда подписываете специально к подписываемой строке 0 в конце добавляете (не знаю зачем), а в файле который csptestу подсовываете он есть? Сертификаты тут не при чем. | ||||
| ||||
Огромное спасибо что не поленились проверить, ток я не понял, подписываемая строка, которую Вам прислал -правильная? "test_test_test" я к ней ноль вроде нигде не добавляю, ноль я добавляю к значению подписи в формате base64. ф-ия CryptBinaryToString возвращает длину значения подписи в формате base64 без завершающего нуля т.е. как strlen(), я добавляю на всяк. случай, а Вы что имели ввиду, напишите пожалуйста??? | ||||
| ||||
Правильная, если 0 добавить. А Вы его добавляете здесь: m_pSignedData ="test_test_test"; pbSignedBuffer = (BYTE*)m_pSignedData; dwSignedDataLen = (DWORD)(strlen(m_pSignedData)+1); с base64 все нормально | ||||
| ||||
А вот Вы о чем так формально нол я не добавляю, он уже есть в строке m_pSignedData ="test_test_test", а длину передаю с учетом этого нуля т.е. strlen()+1 а что в этом неправильного?? я ж не знаю исходники api ф-ий, длина-то ведь им нужна, вероятно чтоб под ней выделить память.. а если длину без ноля передам, дальше она будет обрабатываться, как будто у неё завершающего нуля и нет и выделяться будет так что для заверш. нуля места не останется, или я в чем-то не прав??? а в файл строку я записал для csptesta простым копированием через буфер обмена руками, контрл инс, контрл шифт :)) так что наверное ведь при чтении файла csptest завершающий нуль не обнаружил, так??? т.е мне нужно например fprintf строку в файл запихнуть для проверки?? | ||||
| ||||
Неправильно то, что Вы в файл записываете совсем не то что подписываете. Или записывайте не строку, а pbSignedBuffer (который Вы подписываете) с помощью fwrite, или подписывайте то что в файле лежит - т.е. вместо dwSignedDataLen = (DWORD)(strlen(m_pSignedData)+1) просто dwSignedDataLen = (DWORD)(strlen (m_pSignedData)). Длина функциям нужна чтобы знать что подписывать, иначе как передать бинарный буфер? Им абсолютно наплевать, строка это или вообще одни нули - сколько надо будет памяти в итоге, столько и выделят. | ||||
| ||||
Спасибо большое, ОК у меня вроде последний вопрос, как Вы проверили csptest-ом, ведь сертификат я посылал Вам в файле, а csptest хочет чтоб сертификат был в хранилище my,MY, ???, установили сертификат в это хранилище как-то?? | ||||
| ||||
ксати, если делаю dwSignedDataLen = (DWORD)(strlen (m_pSignedData)) вместо dwSignedDataLen = (DWORD)(strlen(m_pSignedData)+1) то все равно не работает, лучше использую для проверки fwrite, Вы также делали? | ||||
| ||||
Установил путем тыкания в кнопку "Установить сертификат" в окне просмотра. Если не работает, где-то еще ошибка значит... Я взял Ваш текст, подпись и сертификат, подсунул это все csptestу - не проверилось. Добавил к тексту 0 в конце - все стало нормально. Рекомендую попробовать не с detached подписью - если все будет нормально, то значит проблема в чтении/записи исходного текста. | ||||