| ||||
| ||||
Есть пример, котрорый работает для провайдера Микрософт Пытаюсь переделать для Крипто-Про: procedure CryptoPRO_Test_Encrypt_by_password; var err: string; hProv: HCRYPTPROV; //контекст криптопровайдера hash: HCRYPTHASH; //дескриптор хеш-объекта key: HCRYPTKEY; //дескриптор ключа parol : string; i: integer; l: DWORD; data: PByte; inFile, outFile: file; plaintext, ciphertext: string; begin //Получаем контекст провайдера //Crypto-Pro GOST R 34.10-94 Cryptographic Service Provider //тип 75 //if not CryptAcquireContext(@hProv, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) then if not CryptAcquireContext(@hProv, nil, nil, 75, CRYPT_VERIFYCONTEXT) then begin case int64(GetLastError) of ERROR_INVALID_PARAMETER: err := 'ERROR_INVALID_PARAMETER'; ERROR_NOT_ENOUGH_MEMORY: err := 'ERROR_NOT_ENOUGH_MEMORY'; NTE_BAD_FLAGS: err := 'NTE_BAD_FLAGS'; NTE_BAD_KEYSET: err := 'NTE_BAD_KEYSET'; NTE_BAD_KEYSET_PARAM: err := 'NTE_BAD_KEYSET_PARAM'; NTE_BAD_PROV_TYPE: err := 'NTE_BAD_PROV_TYPE'; NTE_BAD_SIGNATURE: err := 'NTE_BAD_SIGNATURE'; NTE_EXISTS: err := 'NTE_EXISTS'; NTE_KEYSET_ENTRY_BAD: err := 'NTE_KEYSET_ENTRY_BAD'; NTE_KEYSET_NOT_DEF: err := 'NTE_KEYSET_NOT_DEF'; NTE_NO_MEMORY: err := 'NTE_NO_MEMORY'; NTE_PROV_DLL_NOT_FOUND: err := 'NTE_PROV_DLL_NOT_FOUND'; NTE_PROV_TYPE_ENTRY_BAD: err := 'NTE_PROV_TYPE_ENTRY_BAD'; NTE_PROV_TYPE_NO_MATCH: err := 'NTE_PROV_TYPE_NO_MATCH'; NTE_PROV_TYPE_NOT_DEF: err := 'NTE_PROV_TYPE_NOT_DEF'; NTE_PROVIDER_DLL_FAIL: err := 'NTE_PROVIDER_DLL_FAIL'; NTE_SIGNATURE_FILE_BAD: err := 'NTE_SIGNATURE_FILE_BAD'; else err := 'Unknown error'; end; MessageDlg('Error of CryptAcquireContext: '+err, mtError, [mbOK], 0); exit; end; //Создаем дескриптор хеш-объекта который будет работать по алгоритму SHA if not CryptCreateHash(hProv, CALG_SHA, 0, 0, @hash) then begin case int64(GetLastError) of ERROR_INVALID_HANDLE: err := 'ERROR_INVALID_HANDLE'; ERROR_INVALID_PARAMETER: err := 'ERROR_INVALID_PARAMETER'; ERROR_NOT_ENOUGH_MEMORY: err := 'ERROR_NOT_ENOUGH_MEMORY'; NTE_BAD_ALGID: err := 'NTE_BAD_ALGID'; NTE_BAD_FLAGS: err := 'NTE_BAD_FLAGS'; NTE_BAD_KEY: err := 'NTE_BAD_KEY'; NTE_NO_MEMORY: err := 'NTE_NO_MEMORY'; else err := 'Unknown error'; end; MessageDlg('Error of CryptCreateHash: '+err, mtError, [mbOK], 0); exit; end; parol := 'angara'; //Создаем хеш пароля if not CryptHashData(hash, @parol[1], length(parol), 0) then begin case int64(GetLastError) of ERROR_INVALID_HANDLE: err := 'ERROR_INVALID_HANDLE'; ERROR_INVALID_PARAMETER: err := 'ERROR_INVALID_PARAMETER'; NTE_BAD_ALGID: err := 'NTE_BAD_ALGID'; NTE_BAD_FLAGS: err := 'NTE_BAD_FLAGS'; NTE_BAD_HASH: err := 'NTE_BAD_HASH'; NTE_BAD_HASH_STATE: err := 'NTE_BAD_HASH_STATE'; NTE_BAD_KEY: err := 'NTE_BAD_KEY'; NTE_BAD_LEN: err := 'NTE_BAD_LEN'; NTE_BAD_UID: err := 'NTE_BAD_UID'; NTE_FAIL: err := 'NTE_FAIL'; NTE_NO_MEMORY: err := 'NTE_NO_MEMORY'; else err := 'Unknown error'; end; MessageDlg('Error of CryptHashData: '+err, mtError, [mbOK], 0); exit; end; До этого места работает //Создаем ключ по хеш-у пароля //для алгортима RC4 ???? - здесь очевидно надо указать //шифрование по ГОСТ - КАК ЭТО СДЕЛАТЬ, КАКИМ ИЗ ТРЕХ ПРОВАЙДЕРОВ КРИПТО_ПРО лучше пользоваться? if not CryptDeriveKey(hProv, CALG_RC4, hash, 0, @key) then begin case int64(GetLastError) of ERROR_INVALID_HANDLE: err := 'ERROR_INVALID_HANDLE'; ERROR_INVALID_PARAMETER: err := 'ERROR_INVALID_PARAMETER'; NTE_BAD_ALGID: err := 'NTE_BAD_ALGID'; NTE_BAD_FLAGS: err := 'NTE_BAD_FLAGS'; NTE_BAD_HASH: err := 'NTE_BAD_HASH'; NTE_BAD_HASH_STATE: err := 'NTE_BAD_HASH_STATE'; NTE_BAD_UID: err := 'NTE_BAD_UID'; NTE_FAIL: err := 'NTE_FAIL'; else err := 'Unknown error'; end; MessageDlg('Error of CryptHashData: '+err, mtError, [mbOK], 0); exit; end; //удаляем хеш-объект if not CryptDestroyHash(hash) then begin case int64(GetLastError) of ERROR_BUSY: err := 'ERROR_BUSY'; ERROR_INVALID_HANDLE: err := 'ERROR_INVALID_HANDLE'; ERROR_INVALID_PARAMETER: err := 'ERROR_INVALID_PARAMETER'; NTE_BAD_ALGID: err := 'NTE_BAD_ALGID'; NTE_BAD_HASH: err := 'NTE_BAD_HASH'; NTE_BAD_UID: err := 'NTE_BAD_UID'; else err := 'Unknown error'; end; MessageDlg('Error of CryptDestroyHash: '+err, mtError, [mbOK], 0); exit; end; //Осталось зашифровать файл MainForm.SaveDialog1.Title := 'Куда сохранить зашифрованные данные?'; MainForm.SaveDialog1.Filter := 'Все файлы (*.*)|*.*|Зашифрованные файлы (*.enc)|*.enc'; MainForm.SaveDialog1.DefaultExt := 'enc'; if MainForm.SaveDialog1.Execute then begin ciphertext := MainForm.SaveDialog1.FileName; AssignFile(inFile, plaintext); AssignFile(outFile, ciphertext); reset(inFile, 1); { Record size = 1 } rewrite(outFile, 1); { Record size = 1 } GetMem(data, 512); while not eof(inFile) do begin BlockRead(inFile, data^, 512, l); //читаем блок, в l - сколько реально считано //шифруем блок ключом из key if not CryptEncrypt(key, 0, //хеш не считаем eof(inFile), //последний ли блок шифруем? 0, //???? data, //данные @l, //размер данных l) // размер буфера then begin case int64(GetLastError) of ERROR_INVALID_HANDLE: err := 'ERROR_INVALID_HANDLE'; ERROR_INVALID_PARAMETER: err := 'ERROR_INVALID_PARAMETER'; NTE_BAD_ALGID: err := 'NTE_BAD_ALGID'; NTE_BAD_DATA: err := 'NTE_BAD_DATA'; NTE_BAD_FLAGS: err := 'NTE_BAD_FLAGS'; NTE_BAD_HASH: err := 'NTE_BAD_HASH'; NTE_BAD_HASH_STATE: err := 'NTE_BAD_HASH_STATE'; NTE_BAD_KEY: err := 'NTE_BAD_KEY'; NTE_BAD_LEN: err := 'NTE_BAD_LEN'; NTE_BAD_UID: err := 'NTE_BAD_UID'; NTE_DOUBLE_ENCRYPT: err := 'NTE_DOUBLE_ENCRYPT'; NTE_FAIL: err := 'NTE_FAIL'; NTE_NO_MEMORY: err := 'NTE_NO_MEMORY'; else err := 'Unknown error'; end; MessageDlg('Error of ncrypt: '+err, mtError, [mbOK], 0); exit; end; BlockWrite(outFile, data^, l); end; FreeMem(data, 512); CloseFile(inFile); CloseFile(outFile); //FileMemo.Lines.Clear; plaintext := ''; ciphertext := ''; //EncryptItem.Enabled := false; end; //освобождаем контекст крипто-провайдера if not CryptReleaseContext(hProv, 0) then begin case int64(GetLastError) of ERROR_BUSY: err := 'ERROR_BUSY'; ERROR_INVALID_HANDLE: err := 'ERROR_INVALID_HANDLE'; ERROR_INVALID_PARAMETER: err := 'ERROR_INVALID_PARAMETER'; NTE_BAD_FLAGS: err := 'NTE_BAD_FLAGS'; NTE_BAD_UID: err := 'NTE_BAD_UID'; else err := 'Unknown error'; end; MessageDlg('Error of CryptReleaseContext: '+err, mtError, [mbOK], 0); end; end; | ||||
Ответы: | ||||
| ||||
//Создаем ключ по хеш-у пароля //для алгортима RC4 ???? - здесь очевидно надо указать //шифрование по ГОСТ - КАК ЭТО СДЕЛАТЬ, КАКИМ ИЗ ТРЕХ ПРОВАЙДЕРОВ КРИПТО_ПРО лучше пользоваться? if not CryptDeriveKey(hProv, CALG_RC4, hash, 0, @key) then Для ГОСТ должно быть так CryptDeriveKey(hProv, CALG_G28147, hash, 0, @key) А алгоритм шифрования выбирается по алгоритму ключа | ||||
| ||||
Также CryptCreateHash нужно вызывать с CALG_GR3411 | ||||