Skip to content

Instantly share code, notes, and snippets.

@linuxaged
Created May 12, 2020 12:16
Show Gist options
  • Save linuxaged/826516796d594989dce6eae3b7f0e6dd to your computer and use it in GitHub Desktop.
Save linuxaged/826516796d594989dce6eae3b7f0e6dd to your computer and use it in GitHub Desktop.
签名算法,错误版本
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