Created
May 12, 2020 12:16
-
-
Save linuxaged/826516796d594989dce6eae3b7f0e6dd to your computer and use it in GitHub Desktop.
签名算法,错误版本
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void HMAC(const char* key, const char* message) { | |
//-------------------------------------------------------------------- | |
// Declare variables. | |
// | |
// hProv: Handle to a cryptographic service provider (CSP). | |
// This example retrieves the default provider for | |
// the PROV_RSA_FULL provider type. | |
// hHash: Handle to the hash object needed to create a hash. | |
// hKey: Handle to a symmetric key. This example creates a | |
// key for the RC4 algorithm. | |
// hHmacHash: Handle to an HMAC hash. | |
// pbHash: Pointer to the hash. | |
// dwDataLen: Length, in bytes, of the hash. | |
// Data1: Password string used to create a symmetric key. | |
// Data2: Message string to be hashed. | |
// HmacInfo: Instance of an HMAC_INFO structure that contains | |
// information about the HMAC hash. | |
// | |
HCRYPTPROV hProv = NULL; | |
HCRYPTHASH hHash = NULL; | |
HCRYPTKEY hKey = NULL; | |
HCRYPTHASH hHmacHash = NULL; | |
PBYTE pbHash = NULL; | |
DWORD dwDataLen = 0; | |
//BYTE Data1[] = {0x70,0x61,0x73,0x73,0x77,0x6F,0x72,0x64}; | |
//BYTE Data2[] = {0x6D,0x65,0x73,0x73,0x61,0x67,0x65}; | |
HMAC_INFO HmacInfo; | |
//-------------------------------------------------------------------- | |
// Zero the HMAC_INFO structure and use the SHA1 algorithm for | |
// hashing. | |
ZeroMemory(&HmacInfo, sizeof(HmacInfo)); | |
HmacInfo.HashAlgid = CALG_SHA_256; | |
//-------------------------------------------------------------------- | |
// Acquire a handle to the default RSA cryptographic service provider. | |
if(!CryptAcquireContext( | |
&hProv, // handle of the CSP | |
NULL, // key container name | |
MS_ENHANCED_PROV, // CSP name | |
PROV_RSA_FULL, // provider type | |
CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) // no key access is requested | |
{ | |
lxd::print(" Error in AcquireContext {} \n", | |
GetLastError()); | |
goto ErrorExit; | |
} | |
//-------------------------------------------------------------------- | |
// Derive a symmetric key from a hash object by performing the | |
// following steps: | |
// 1. Call CryptCreateHash to retrieve a handle to a hash object. | |
// 2. Call CryptHashData to add a text string (password) to the | |
// hash object. | |
// 3. Call CryptDeriveKey to create the symmetric key from the | |
// hashed password derived in step 2. | |
// You will use the key later to create an HMAC hash object. | |
if(!CryptCreateHash( | |
hProv, // handle of the CSP | |
CALG_HMAC, // hash algorithm to use | |
0, // hash key | |
0, // reserved | |
&hHash)) // address of hash object handle | |
{ | |
lxd::print("Error in CryptCreateHash {0:x} \n", | |
GetLastError()); | |
goto ErrorExit; | |
} | |
{ | |
struct BlobHeader { | |
BLOBHEADER header; | |
uint32_t keySize; | |
}; | |
BlobHeader keyBlobHeader; | |
keyBlobHeader.header.bType = PLAINTEXTKEYBLOB; | |
keyBlobHeader.header.bVersion = CUR_BLOB_VERSION; | |
keyBlobHeader.header.reserved = 0; | |
keyBlobHeader.header.aiKeyAlg = CALG_RC2; | |
keyBlobHeader.keySize = strlen(key); | |
std::vector<BYTE> key_blob(sizeof(keyBlobHeader) + strlen(key)); | |
memcpy(key_blob.data(), &keyBlobHeader, sizeof(keyBlobHeader)); | |
memcpy(key_blob.data() + sizeof(keyBlobHeader), key, strlen(key)); | |
if(!CryptImportKey(hProv, key_blob.data(), sizeof(keyBlobHeader) + strlen(key), 0, CRYPT_IPSEC_HMAC_KEY, &hKey)) { | |
lxd::print("Error when CryptImportKey {0:x}\n", GetLastError()); | |
goto ErrorExit; | |
} | |
} | |
//if(!CryptHashData( | |
// hHash, // handle of the hash object | |
// (const BYTE*)key, // password to hash | |
// strlen(key), // number of bytes of data to add | |
// 0)) // flags | |
//{ | |
// lxd::print("Error in CryptHashData {0:x} \n", | |
// GetLastError()); | |
// goto ErrorExit; | |
//} | |
if(!CryptDeriveKey( | |
hProv, // handle of the CSP | |
CALG_RC4, // algorithm ID | |
hHash, // handle to the hash object | |
0, // flags | |
&hKey)) // address of the key handle | |
{ | |
lxd::print("Error in CryptDeriveKey {0:x} \n", | |
GetLastError()); | |
goto ErrorExit; | |
} | |
//-------------------------------------------------------------------- | |
// Create an HMAC by performing the following steps: | |
// 1. Call CryptCreateHash to create a hash object and retrieve | |
// a handle to it. | |
// 2. Call CryptSetHashParam to set the instance of the HMAC_INFO | |
// structure into the hash object. | |
// 3. Call CryptHashData to compute a hash of the message. | |
// 4. Call CryptGetHashParam to retrieve the size, in bytes, of | |
// the hash. | |
// 5. Call malloc to allocate memory for the hash. | |
// 6. Call CryptGetHashParam again to retrieve the HMAC hash. | |
if(!CryptCreateHash( | |
hProv, // handle of the CSP. | |
CALG_HMAC, // HMAC hash algorithm ID | |
hKey, // key for the hash (see above) | |
0, // reserved | |
&hHmacHash)) // address of the hash handle | |
{ | |
lxd::print("Error in CryptCreateHash {0:x} \n", | |
GetLastError()); | |
goto ErrorExit; | |
} | |
if(!CryptSetHashParam( | |
hHmacHash, // handle of the HMAC hash object | |
HP_HMAC_INFO, // setting an HMAC_INFO object | |
(BYTE*)&HmacInfo, // the HMAC_INFO object | |
0)) // reserved | |
{ | |
lxd::print("Error in CryptSetHashParam {} \n", | |
GetLastError()); | |
goto ErrorExit; | |
} | |
if(!CryptHashData( | |
hHmacHash, // handle of the HMAC hash object | |
(const BYTE*)message, // message to hash | |
strlen(message), // number of bytes of data to add | |
0)) // flags | |
{ | |
lxd::print("Error in CryptHashData {} \n", | |
GetLastError()); | |
goto ErrorExit; | |
} | |
//-------------------------------------------------------------------- | |
// Call CryptGetHashParam twice. Call it the first time to retrieve | |
// the size, in bytes, of the hash. Allocate memory. Then call | |
// CryptGetHashParam again to retrieve the hash value. | |
if(!CryptGetHashParam( | |
hHmacHash, // handle of the HMAC hash object | |
HP_HASHVAL, // query on the hash value | |
NULL, // filled on second call | |
&dwDataLen, // length, in bytes, of the hash | |
0)) { | |
lxd::print("Error in CryptGetHashParam {} \n", | |
GetLastError()); | |
goto ErrorExit; | |
} | |
pbHash = (BYTE*)malloc(dwDataLen); | |
if(NULL == pbHash) { | |
lxd::print("unable to allocate memory\n"); | |
goto ErrorExit; | |
} | |
if(!CryptGetHashParam( | |
hHmacHash, // handle of the HMAC hash object | |
HP_HASHVAL, // query on the hash value | |
pbHash, // pointer to the HMAC hash value | |
&dwDataLen, // length, in bytes, of the hash | |
0)) { | |
lxd::print("Error in CryptGetHashParam {} \n", GetLastError()); | |
goto ErrorExit; | |
} | |
// Print the hash to the console. | |
lxd::print("The hash is: "); | |
for(DWORD i = 0; i < dwDataLen; i++) { | |
lxd::print("{}", (char)(pbHash[i])); | |
} | |
lxd::print("\n"); | |
// Free resources. | |
ErrorExit: | |
if(hHmacHash) | |
CryptDestroyHash(hHmacHash); | |
if(hKey) | |
CryptDestroyKey(hKey); | |
if(hHash) | |
CryptDestroyHash(hHash); | |
if(hProv) | |
CryptReleaseContext(hProv, 0); | |
if(pbHash) | |
free(pbHash); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment