来源:https://blog.csdn.net/dlfer11/article/details/50345159 上次我们讲了Microsoft CryptoAPI的构成以及会话密钥的使用。接下来我们将看一下公私密钥对的使用、HASH算法、数字签名等技术。 一、 公用密钥加密技术 那么,怎么得到这些密钥对呢? if(CryptGetUserKey( hCryptProv, // 我们已经得到的CSP句柄 AT_SIGNATURE, // 这里想得到signature key pair &hKey)) // 返回密钥句柄 { printf("A signature key is available./n"); } else //取signature key pair错误 { printf("No signature key is available./n"); if(GetLastError() == NTE_NO_KEY) //密钥容器里不存在signature key pair { // 创建 signature key pair. printf("The signature key does not exist./n"); printf("Create a signature key pair./n"); if(CryptGenKey( hCryptProv, //CSP句柄 AT_SIGNATURE, //创建的密钥对类型为signature key pair 0, //key类型,这里用默认值 &hKey)) //创建成功返回新创建的密钥对的句柄 { printf("Created a signature key pair./n"); } else { printf ("Error occurred creating a signature key./n"); } } else { printf ("An error other than NTE_NO_KEY getting signature/key./n"); } } // end if 将参数AT_SIGNATURE换成AT_KEYEXCHANGE就可以得到key exchange key pair。 BOOL WINAPI CryptExportKey( HCRYPTKEY hKey, HCRYPTKEY hExpKey, DWORD dwBlobType, DWORD dwFlags, BYTE* pbData, DWORD* pdwDataLen ); hKey:需要被导出的密钥句柄 下面的例子演示如何导出密钥。 if(CryptExportKey( hKey, NULL, PUBLICKEYBLOB, //导出公钥 0, NULL, &dwBlobLen)) //返回密钥数据长度 { printf("Size of the BLOB for the public key determined. /n"); } else { printf("Error computing BLOB length./n"); exit(1); } //-------------------------------------------------------------------- // Allocate memory for the pbKeyBlob. if(pbKeyBlob = (BYTE*)malloc(dwBlobLen)) { printf("Memory has been allocated for the BLOB. /n"); } else { printf("Out of memory. /n"); exit(1); } //-------------------------------------------------------------------- // Do the actual exporting into the key BLOB. if(CryptExportKey( hKey, NULL, PUBLICKEYBLOB, 0, pbKeyBlob, //返回密钥数据 &dwBlobLen)) //导出的密钥数据的长度 { printf("Contents have been written to the BLOB. /n"); } else { printf("Error exporting key./n"); exit(1); } 如果要导出用公用密钥加密技术加密的密钥,只要把API的第二个参数传入一个key exchange key pair句柄就可以了。 既然有了导出当然要有导入。 BOOL WINAPI CryptImportKey( HCRYPTPROV hProv, //CSP句柄 BYTE* pbData, //要导入的密钥数据 DWORD dwDataLen, //数据长度 HCRYPTKEY hPubKey, //如果数据是被加密的这里输入解密用的密钥句柄 DWORD dwFlags, //标志位 HCRYPTKEY* phKey //导入后返回的密钥句柄 ); 这个API比较简单,这里就不举例说明了,在以后的例子里会看到。 二、 HASH 下面的API用来创建hash对象 BOOL WINAPI CryptCreateHash( HCRYPTPROV hProv, //CSP句柄 ALG_ID Algid, //选择hash算法,比如CALG_MD5等 HCRYPTKEY hKey, //HMAC 和MAC算法时有用 DWORD dwFlags, //保留,传入0即可 HCRYPTHASH* phHash //返回hash句柄 ); if(CryptCreateHash( hCryptProv, CALG_MD5, 0, 0, &hHash)) { printf("An empty hash object has been created. /n"); } else { printf("Error during CryptBeginHash!/n"); exit(1); } // Insert code that uses the hash object here. //-------------------------------------------------------------------- // After processing, hHash must be released. if(hHash) CryptDestroyHash(hHash); //释放句柄 我们已经得到hash对象了,下面就找点数据试试,咱也去哈一下,当然这里可不是哈日哈韩的哈,更不是哈巴狗的哈,嘿嘿。Let’s go!! BOOL WINAPI CryptHashData( HCRYPTHASH hHash, //hash对象 BYTE* pbData, //被hash的数据 DWORD dwDataLen, //数据的长度 DWORD dwFlags //微软的CSP这个值会被忽略 ); 下面代码: BYTE *pbBuffer= (BYTE *)"The data that is to be hashed."; DWORD dwBufferLen = strlen((char *)pbBuffer)+1; if(CryptHashData( hHash, pbBuffer, dwBufferLen, 0)) { printf("The data buffer has been added to the hash./n"); } else { printf("Error during CryptHashData./n"); exit(1); }
BYTE *pbHash; BYTE *pbHashSize; DWORD dwHashLen = sizeof(DWORD); DWORD i; if(!(pbHashSize =(BYTE *) malloc(dwHashLen))) MyHandleError("Memory allocation failed."); //下面的这次调用我没搞清楚:( 我怎么觉得没有必要!! if(CryptGetHashParam( hHash, HP_HASHSIZE, //取hash数据的大小 pbHashSize, //输出hash数据大小的缓冲区 &dwHashLen, //缓冲区大小 0)) { // It worked. Free pbHashSize. free(pbHashSize); } else { MyHandleError("CryptGetHashParam failed to get size."); } if(CryptGetHashParam( hHash, HP_HASHVAL, //取hash值 NULL, //设为NULL,在dwHashLen返回需要的输出缓冲区大小 &dwHashLen, //输出缓冲区大小 0)) { // It worked. Do nothing. } else { MyHandleError("CryptGetHashParam failed to get length."); } if(pbHash = (BYTE*)malloc(dwHashLen)) { // It worked. Do nothing. } else { MyHandleError("Allocation failed."); } if(CryptGetHashParam( hHash, HP_HASHVAL, //取hash值 pbHash, //返回Hash数据 &dwHashLen, //hash数据长度 0)) { // Print the hash value. printf("The hash is: "); for(i = 0 ; i < dwHashLen ; i++) { printf("%2.2x ",pbHash[i]); } printf("/n"); } else { MyHandleError("Error during reading hash value."); } free(pbHash);
|
|
来自: 株野 > 《MS Crypt》