17.10.2007 16:14:39CryptoApi win 2000 Ответов: 7
Георгий
Здравствуйте, столкнулся с проблеммой. Не получается под windows 2000 расшифровать файл закриптованный в win xp открытым ключем сгенерированным там же(winxp). Закрытая ключевая пара экспортируется и импортируется без пароля в файл. Алгоритм RSA_FULL, длина открытого ключа 1024 бита. Может есть какое-нибудь обновление для win 2000 или рекомендации.
Заранее спасибо за ответ. И извиняюсь за такой простой вопрос. Cам на микрософте ответ найти не смог... :)
 
Ответы:
17.10.2007 17:02:14Kirill Sobolev
а на ХР нормально расшифровывается?
17.10.2007 17:08:53Георгий
Да, нормально. И если сгенерено на одном компьютере с xp, а импортируется и расшифровывается на другом, тоже все работает...
17.10.2007 17:59:34Kirill Sobolev
А чем Вы шифруете?
17.10.2007 18:13:42Георгий
хм... Своя програмка написанная на delphi с использованием Wcrypt2.pas для доступа к апи...
18.10.2007 11:31:46Kirill Sobolev
А на код, выполняющий шифрование, посмотреть можно?
18.10.2007 11:43:37Георгий
Это 4 процедуры. Первая - криптование, вторая - импорт ключа из файла, 3 - экспорт, 4 - декриптование.

procedure cryEncrypt(FileName,EncFileName,PublicKeyName,SetName:string);
begin
if not FileExists(PublicKeyName) then
begin
showmessage('Не получается найти файл открытого ключа...');
exit;
end;

err := SetName;
cont := StrAlloc(length(err) + 1);
StrPCopy(cont, err);
if not CryptAcquireContext(@hProv, cont, nil, PROV_RSA_FULL, 0) then
begin
crypterr('CryptAcquireContext');
exit;
end;
AssignFile(f, PublicKeyName); //=PublicKey
reset(f, 1);
buflen := FileSize(f);
GetMem(buf, buflen);
BlockRead(f, buf^, buflen);
CloseFile(f);

if not CryptImportKey(hProv, buf, buflen, 0, CRYPT_EXPORTABLE, @key) then
begin
crypterr('CryptImportKey');
FreeMem(buf, buflen);
exit;
end;



FreeMem(buf, buflen);
AssignFile(inFile, FileName); //=test.txt
AssignFile(outFile, EncFileName); //=test.enc
reset(inFile, 1);
rewrite(outFile, 1);
GetMem(data, 256);
l:=0;

if not CryptEncrypt(Key,0,true,0,nil,@l,0) then
begin
crypterr('CryptEncrypt');
exit;
end;
while not eof(inFile) do
begin
Application.ProcessMessages;
if iHalt=999 then
begin
FreeMem(data, 256);
CloseFile(inFile);
CloseFile(outFile);
ihalt:=0;
exit;
end;
BlockRead(inFile, data^, l-11, l);
if not CryptEncrypt(key, 0, eof(infile), 0,
data, @l, 128) then
begin
crypterr('CryptEncrypt');
exit;
end;
BlockWrite(outFile, data^, l);
end;
FreeMem(data, 256);
CloseFile(inFile);
CloseFile(outFile);
end;


procedure cryImportKey(const publickey,privatekey:boolean;const publickeyName,privatekeyName,passPrivExport,setName:string);
begin
err := setName;
cont := StrAlloc(length(err) + 1);
StrPCopy(cont, err);
if not CryptAcquireContext(@hProv, cont, nil, PROV_RSA_FULL, 0) then
begin
crypterr('CryptAcquireContext');
exit;
end;

//Импортируем ключевую пару целиком
if privatekey then
begin
if not CryptCreateHash(hProv, CALG_SHA, 0, 0, @hash) then
begin
crypterr('CryptCreateHash');
exit;
end;
if not CryptHashData(hash, @(passPrivExport), length(passPrivExport),0) then
begin
crypterr('CryptHashData');
exit;
end;
if not CryptDeriveKey(hProv, CALG_RC2, hash, 0, @exchkey) then
begin
crypterr('CryptDeriveKey');
exit;
end;
AssignFile(f, privatekeyName); //=privKey
reset(f, 1);
buflen := FileSize(f);
GetMem(buf, buflen);
BlockRead(f, buf^, buflen);
CloseFile(f);
if not CryptImportKey(hProv, buf, buflen, exchKey, CRYPT_EXPORTABLE, @key) then
begin
crypterr('CryptImportKey');
FreeMem(buf, buflen);
exit;
end;
if not CryptDestroyKey(key) then
begin
crypterr('CryptDestroyKey');
FreeMem(buf, buflen);
exit;
end;
if not CryptDestroyHash(Hash) then
begin
crypterr('CryptDestroyHash');
FreeMem(buf, buflen);
exit;
end;
if not CryptReleaseContext(hProv, 0) then
begin
crypterr('CryptReleaseContext');
FreeMem(buf, buflen);
exit;
end;
FreeMem(buf, buflen);
end;

//Импортируем только публичный ключ.
if publickey then
begin
AssignFile(f, publickeyName); //=publicKey
reset(f, 1);
buflen := FileSize(f);
GetMem(buf, buflen);
BlockRead(f, buf^, buflen);
CloseFile(f);
if not CryptImportKey(hProv, buf, buflen, 0, CRYPT_EXPORTABLE, @key) then
begin
crypterr('CryptImportKey');
FreeMem(buf, buflen);
exit;
end;
if not CryptDestroyKey(key) then
begin
crypterr('CryptDestroyKey');
FreeMem(buf, buflen);
exit;
end;
if not CryptReleaseContext(hProv, 0) then
begin
crypterr('CryptReleaseContext');
FreeMem(buf, buflen);
exit;
end;
FreeMem(buf, buflen);
end;
end;


//Экспорт публичного ключа или ключевой пары.
procedure cryExportKey(const publicKey,privateKey:boolean;const publicKeyName,privateKeyName,passPrivExport,setName:string);
begin
//Экспортируем публичный ключ
if publicKey then
begin
if not CryptAcquireContext(@hProv, cont, nil, PROV_RSA_FULL, 0) then
begin
crypterr('CryptAcquireContext');
freemem(pbuf);
exit;
end;
if not CryptGetUserKey(hprov,AT_KEYEXCHANGE,@key) then
begin
crypterr('CryptGetUserKey');
freemem(pbuf);
exit;
end;
if not CryptExportKey(key, 0, PUBLICKEYBLOB, 0, nil, @bufLen) then
begin
crypterr('CryptExportKey');
freemem(pbuf);
exit;
end;
getmem(pbuf, bufLen);
if not CryptExportKey(key, 0, PUBLICKEYBLOB, 0, pbuf, @bufLen) then
Begin
crypterr('CryptExportKey');
freemem(pbuf);
exit;
end;
if not CryptDestroyKey(key) then
Begin
crypterr('CryptDestroyKey');
freemem(pbuf);
exit;
end;
if not CryptReleaseContext(hProv, 0) then
Begin
crypterr('CryptReleaseContext');
freemem(pbuf);
exit;
end;
AssignFile(f, publicKeyName); //=publickey
rewrite(f, 1);
BlockWrite(f, pbuf^, bufLen);
CloseFile(f);
freemem(pbuf);
end;

//Экспортируем ключевую пару.
if privateKey then
begin
err := setName;;
cont := StrAlloc(length(err) + 1);
StrPCopy(cont, err);
if not CryptAcquireContext(@hProv, cont, nil, PROV_RSA_FULL, 0) then
begin
crypterr('CryptAcquireContext');
freemem(pbuf);
exit;
end;
if not CryptCreateHash(hProv, CALG_SHA, 0, 0, @hash) then
begin
crypterr('CryptCreateHash');
freemem(pbuf);
exit;
end;
if not CryptHashData(hash, @(passPrivExport), length(passPrivExport),0) then
begin
crypterr('CryptHashData');
freemem(pbuf);
exit;
end;
if not CryptDeriveKey(hProv, CALG_RC2, hash, 0, @exchkey) then
begin
crypterr('CryptDeriveKey');
freemem(pbuf);
exit;
end;
if not CryptGetUserKey(hprov,AT_KEYEXCHANGE,@key) then
begin
crypterr('CryptGetUserKey');
freemem(pbuf);
exit;
end;
if not CryptExportKey(key, exchKey, PRIVATEKEYBLOB, 0, nil, @bufLen) then
begin
crypterr('CryptExportKey');
freemem(pbuf);
exit;
end;
getmem(pbuf, bufLen);
if not CryptExportKey(key, exchKey, PRIVATEKEYBLOB, 0, pbuf, @bufLen) then
begin
crypterr('CryptExportKey');
freemem(pbuf);
exit;
end;
if not CryptDestroyKey(key) then
Begin
crypterr('CryptDestroyKey');
freemem(pbuf);
exit;
end;
if not CryptDestroyHash(hash) then
begin
crypterr('CryptDestroyHash');
freemem(pbuf);
exit;
end;
if not CryptReleaseContext(hProv, 0) then
begin
crypterr('CryptReleaseContext');
freemem(pbuf);
exit;
end;
AssignFile(f, privateKeyName); //=privkey
rewrite(f, 1);
BlockWrite(f, pbuf^, bufLen);
CloseFile(f);
freemem(pbuf);
end;
end;


//Раскриптовать файл.
procedure cryDecrypt(EncFileName,FileName,PrivateKeyName,SetName:string);
var
passprivExport: string;
begin
if not FileExists(PrivateKeyName) then
begin
showmessage('Не получается найти файл закрытого ключа...');
exit;
end;

err := SetName;
cont := StrAlloc(length(err) + 1);
StrPCopy(cont, err);
if not CryptAcquireContext(@hProv, cont, nil, PROV_RSA_FULL, 0) then
begin
crypterr('CryptAcquireContext');
exit;
end;

if not CryptGetUserKey(hprov,AT_KEYEXCHANGE,@key) then
begin
crypterr('CryptGetUserKey');
exit;
end;
if not CryptSetKeyParam(Key, KP_IV, @buf, 0) then
begin
crypterr('CryptGetUserKey');
exit;
end;
AssignFile(inFile, EncFileName); //=test.enc
AssignFile(outFile, FileName); //-test2.txt
reset(inFile, 1);
rewrite(outFile, 1);
GetMem(data, 256);
l:=0;

if not CryptDecrypt(Key,0,true,0,nil,@l) then
begin
crypterr('CryptEncrypt');
exit;
end;

while not eof(inFile) do
begin
Application.ProcessMessages;
if iHalt=999 then
begin
FreeMem(data, 256);
CloseFile(inFile);
CloseFile(outFile);
ihalt:=0;
exit;
end;
l:=128;
BlockRead(inFile, data^, l, l);
if not CryptDecrypt(key, 0,eof(infile) , 0,
data, @l) then
begin
crypterr('CryptDecrypt');
exit;
end;
BlockWrite(outFile, data^, l);
end;
FreeMem(data, 256);
CloseFile(inFile);
CloseFile(outFile);
end;
18.10.2007 18:01:10Kirill Sobolev
Возможно, у Вас отсутствует Microsoft Enhanced Cryptographic Provider. А в каком месте ошибка появляется?