2010-05-28 3 views
4

SHA1 해시가 있으며 서명해야합니다. CryptSignHash() 메서드는 서명을 위해 HCRYPTHASH 핸들이 필요합니다. 생성하고 실제 해시 값을 이미 설정 했으므로 다음과 같이 설정하십시오.SHA1을 Microsoft CAPI와 함께 사용

CryptCreateHash(cryptoProvider, CALG_SHA1, 0, 0, &hash); 
CryptSetHashParam(hash, HP_HASHVAL, hashBytes, 0); 

hashBytes는 20 바이트의 배열입니다.

그러나이 HCRYPTHASH 핸들에서 생성 된 서명이 올바르지 않은 것이 문제입니다. 문제를 추적하여 CAPI가 실제로 hashBytes 배열의 20 바이트를 모두 사용하지 않는다는 사실을 확인했습니다. 어떤 이유로 SHA1은 단지 4 바이트라고 생각합니다.

HCRYPTPROV cryptoProvider; 
CryptAcquireContext(&cryptoProvider, NULL, NULL, PROV_RSA_FULL, 0); 

HCRYPTHASH hash; 
HCRYPTKEY keyForHash; 
CryptCreateHash(cryptoProvider, CALG_SHA1, keyForHash, 0, &hash); 

DWORD hashLength; 
CryptGetHashParam(hash, HP_HASHSIZE, NULL, &hashLength, 0); 
printf("hashLength: %d\n", hashLength); 

그리고이 hashLength 출력한다 : 4

내가이 작은 프로그램을 작성이를 확인하세요!

누구나 내가 뭘 잘못하고 있는지 설명하거나 Microsoft CAPI가 SHA1이 20 바이트 (160 비트) 대신 4 바이트 (32 비트)라고 생각하는 이유를 설명 할 수 있습니까?

답변

1

그런 식으로 CryptCreateHash을 사용할 수 있다고 생각하지 않습니다. MSDN에서 :

"은 수 CryptCreateHash 함수 는 데이터 스트림의 해시를 개시한다."

즉, 비어있는 것 이외의 방법으로 해시 컨텍스트를 인스턴스화 할 수없는 것처럼 보입니다.

해시를 현재 어떻게 가지고 있습니까? 바이트 배열입니까? 그렇다면 아마 그 배열에 서명하기를 원할 것입니다. 나는 CryptSignMessage 또는 CryptSignMessageWithKey을 조사 할 것입니다.

(내가 추측하고있어,하지만 당신이보고있는하는 것은 해시 상황이 몇 가지 작업을 수행 한 후까지 설정되지 않은 출력 해시의 길이에 의해 설명 될 수있다.)

2

은 작은 오류가 있습니다 당신의 암호. 대신

DWORD hashLength; 
CryptGetHashParam(hash, HP_HASHSIZE, NULL, &hashLength, 0); 
printf("hashLength: %d\n", hashLength); 

의 예상대로

DWORD hashLength, hashSize; 
hashLength = sizeof(DWORD) 
CryptGetHashParam(hash, HP_HASHSIZE, (PBYTE)&hashSize, &hashLength, 0); 
printf("hashSize: %d\n", hashSize); 

는 다음 (20)를 받게됩니다 사용해야합니다.

CryptSignHash 이후의 사용은 CryptSetHashParam 후에도 작동해야합니다. CryptSetHashParam의 설명 끝에있는 설명을 http://msdn.microsoft.com/en-us/library/aa380270(VS.85).aspx에 표시하십시오. 서명 결과를 가져 오는 동안 CryptGetHashParam(..., HP_HASHSIZE, ...)과 동일한 오류가 발생했다고 가정합니다. 코드를 CryptSignHashhttp://msdn.microsoft.com/en-us/library/aa380280(VS.85).aspx의 설명에서 코드와 비교하십시오.