| ||||
| ||||
Есть текстовый файл и есть два eToken. Подписываю первой подписью - всё ОК. Далее подписываю второй подписью (см. функцию) - сваливается с ошибкой 0х80090016 на функции CryptMsgControl(... , CMSG_CTRL_ADD_SIGNER, ...). В чем проблема? function TfrMain.CosignMessage(pSignedMessageBlob: CRYPT_DATA_BLOB; pCosignedMessageBlob: CRYPT_DATA_BLOB; hCertStoreHandle: HCERTSTORE; pCosignerCert: PCCERT_CONTEXT ): CRYPT_DATA_BLOB; var fReturn: boolean; hMsg: HCRYPTMSG; hProv: HCRYPTPROV; cbCosignedMessageBlob: DWORD; pbCosignedMessageBlob: PBYTE; CosignerInfo: CMSG_SIGNER_ENCODE_INFO; CosignCertBlob: CERT_BLOB; dwKeySpec: DWORD; err: String; SignKey: PHCRYPTKEY; cablob: CRYPT_ATTR_BLOB; ca: CRYPT_ATTRIBUTE; pbAuth: PBYTE; cbAuth: DWORD; fileTime: TFILETIME; systemTime: TSYSTEMTIME; begin fReturn := false; hMsg := nil; hProv:= 0; // Initialize the output pointer. pCosignedMessageBlob.cbData := 0; pCosignedMessageBlob.pbData := nil; if not CryptAcquireCertificatePrivateKey(pCosignerCert, 0, nil, @hProv, dwKeySpec, nil) then begin err := IntToStr(GetLastError); Application.MessageBox(PChar('CryptAcquireCertificatePrivateKey ' + err), nil, MB_ICONERROR); exit; end; // Open a message for decoding. hMsg := CryptMsgOpenToDecode(MY_ENCODING_TYPE, 0, 0, 0, nil, nil); if hMsg = nil then begin err := IntToStr(GetLastError); Application.MessageBox(PChar('CryptMsgOpenToDecode ' + err), nil, MB_ICONERROR); exit; end; // Update the message with the encoded BLOB. if not CryptMsgUpdate(hMsg, pSignedMessageBlob.pbData, pSignedMessageBlob.cbData, TRUE) then begin err := IntToStr(GetLastError); Application.MessageBox(PChar('CryptMsgUpdate ' + err), nil, MB_ICONERROR); exit; end; // Initialize the CMSG_SIGNER_ENCODE_INFO structure for the cosigner. FillChar(CosignerInfo, SizeOf(CMSG_SIGNER_ENCODE_INFO), #0 ); CosignerInfo.cbSize := sizeof(CMSG_SIGNER_ENCODE_INFO); CosignerInfo.pCertInfo := pCosignerCert.pCertInfo; CosignerInfo.hCryptProv := hProv; CosignerInfo.dwKeySpec := AT_SIGNATURE; CosignerInfo.HashAlgorithm.pszObjId := szOID_RSA_SHA1RSA; GetSystemTime(systemTime); SystemTimeToFileTime(systemTime, fileTime); // Îïðåäåëèì òðåáóåìóþ äëèíó äëÿ õðàíåíèÿ âðåìåíè*/ CryptEncodeObject(MY_ENCODING_TYPE, szOID_RSA_signingTime, @fileTime, nil, @cbAuth); GetMem(pbAuth,cbAuth); // Êîäèðîâàíèå âðåìåíè â àòðèáóò òèïà szOID_RSA_signingTime */ CryptEncodeObject(MY_ENCODING_TYPE, szOID_RSA_signingTime, @fileTime, pbAuth, @cbAuth); cablob.cbData := cbAuth; cablob.pbData := pbAuth; ca.pszObjId := szOID_RSA_signingTime; ca.cValue := 1; ca.rgValue := @cablob; CosignerInfo.cAuthAttr := 1; CosignerInfo.rgAuthAttr := @ca; // Add the cosigner to the message. if not CryptMsgControl(hMsg, 0, CMSG_CTRL_ADD_SIGNER, @CosignerInfo) then begin err := IntToStr(GetLastError); Application.MessageBox(PChar('CryptMsgControl CMSG_CTRL_ADD_SIGNER ' + err), nil, MB_ICONERROR); exit; end; // Add the cosigner's certificate to the message. CosignCertBlob.cbData := pCosignerCert.cbCertEncoded; CosignCertBlob.pbData := pCosignerCert.pbCertEncoded; if not CryptMsgControl(hMsg, 0, CMSG_CTRL_ADD_CERT, @CosignCertBlob) then begin err := IntToStr(GetLastError); Application.MessageBox(PChar('CryptMsgControl CMSG_CTRL_ADD_CERT ' + err), nil, MB_ICONERROR); exit; end; // Get the size of the cosigned BLOB. if not CryptMsgGetParam(hMsg, CMSG_ENCODED_MESSAGE, 0, nil, @cbCosignedMessageBlob) then begin err := IntToStr(GetLastError); Application.MessageBox(PChar('Get the size of the cosigned BLOB error-' + err), nil, MB_ICONERROR); exit; end; // Allocate memory for the cosigned BLOB. GetMem(pbCosignedMessageBlob, cbCosignedMessageBlob); // Get the cosigned message BLOB. if (CryptMsgGetParam(hMsg, CMSG_ENCODED_MESSAGE, 0, pbCosignedMessageBlob, @cbCosignedMessageBlob)) then begin // pbSignedMessageBlob now contains the signed BLOB. fReturn := true; end else begin err := IntToStr(GetLastError); Application.MessageBox(PChar('Get the cosigned message BLOB error-' + err), nil, MB_ICONERROR); exit; end; // Clean up and free memory as needed. if hMsg <> nil then CryptMsgClose(hMsg); if hProv <> 0 then begin CryptReleaseContext(hProv, 0); hProv := 0; end; // Only free the cosigned message if a failure occurred. if not fReturn then begin if pbCosignedMessageBlob <> nil then begin Freemem(pbCosignedMessageBlob); pbCosignedMessageBlob := nil; end; end; if pbCosignedMessageBlob <> nil then begin pCosignedMessageBlob.cbData := cbCosignedMessageBlob; pCosignedMessageBlob.pbData := pbCosignedMessageBlob; end; result := pCosignedMessageBlob; end; | ||||
Ответы: | ||||
| ||||
Кстати, если в качестве носителя использовать дискету, то этот код работает. Не уж то есть разница с какого носителя вести чтение? | ||||
| ||||
CosignerInfo.dwKeySpec := AT_SIGNATURE; CosignerInfo.HashAlgorithm.pszObjId := szOID_RSA_SHA1RSA; Первая строка - допущение, вторая - не должна использоваться с Крипто-Про CSP, да и вообще это не алгоритм хэширования | ||||