Encoding and Decoding Data
下面逐渐进入主题了,现在来讲讲是如何对数据进行Encoding and Decoding的。依旧是从一段程序中开始。
#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void MyHandleError(char *s);
void main(void)
{
HCRYPTMSG hMsg; 指向一个消息句柄
BYTE* pbContent; 一个BYTE指针指向消息
DWORD cbContent; 消息长度
DWORD cbEncodedBlob; ECODE的BLOB的大小
BYTE *pbEncodedBlob; 一个BYTE指针指向ENCODE BLOB
DWORD cbData = sizeof(DWORD); 数据大小
DWORD cbDecoded; Decode内容大小
BYTE *pbDecoded; 指向Decode的指针
pbContent = (BYTE*) "Security is our only business";
cbContent = strlen((char *) pbContent)+1;
printf("The original message => %s/n",pbContent);
if(cbEncodedBlob = CryptMsgCalculateEncodedLength(
MY_ENCODING_TYPE, 指定Encode类型,在程序的开头已经预定义了,MY_ENCODING_TYPE 就是 PKCS_7_ASN_ENCODING | X509_ASN_ENCODING
0, // Flags
CMSG_DATA, 定义了数据的类型,这里指定为BYTE型的字符串
NULL,
NULL,
cbContent)) 内容的大小
这里的的函数的作用是计算指定消息Encode所需要的最大的长度,通过计算,为一个BLOB分配内存空间。
{
printf("The length of the data has been calculated. /n");
}
else
{
MyHandleError("Getting cbEncodedBlob length failed");
}
为encode blob分配内存空间
if(pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob))
{
printf("Memory has been allocated for the signed message. /n");
}
else
{
MyHandleError("Memory allocation failed");
}
if(hMsg = CryptMsgOpenToEncode( CryptMsgOpenToEncode为Encode,开一个消息
MY_ENCODING_TYPE, Encode类型,文件开始有说明
0, // Flags
CMSG_DATA, 指定Message的类型,CMSG_DATA说明类型没用到
NULL, 现在没有到,为NULL
NULL, 同上
NULL)) 不是流加密,这个参数为NULL
{
printf("The message to be encoded has been opened. /n");
}
else
{
MyHandleError("OpenToEncode failed");
}
if(CryptMsgUpdate( CryptMsgUpdate将数据加到消息中,可以通过循环,将数据一段段的加得到消息中
hMsg, 一个小心句柄
pbContent, 指向数据的指针
cbContent, 数据的大小
TRUE)) TRUE表明这个是最后一段数据,在开个消息的时候,如果CMSG_DETACHED_FLAG有使用到,这设为FALSE,否则为TRUE。
{
printf("Content has been added to the encoded message. /n");
}
else
{
MyHandleError("MsgUpdate failed");
}
if(CryptMsgGetParam( CryptMsgGetParam是获取一个消息中的参数
hMsg, 一个消息句柄
CMSG_BARE_CONTENT_PARAM, 指定要获取的参数的类型
0,
pbEncodedBlob, 一个接受数据的内存地址
&cbEncodedBlob)) BLOB的大小,即是上面接受的数据的大小
{
printf("Message encoded successfully. /n");
}
else
{
MyHandleError("MsgGetParam failed");
}
释放消息句柄
if(hMsg)
CryptMsgClose(hMsg);
if(hMsg = CryptMsgOpenToDecode( 开个Decode的小心句柄,参数和上面的Encode一样
MY_ENCODING_TYPE,
0,
CMSG_DATA,
NULL,
NULL,
NULL))
{
printf("The message to decode is open. /n");
}
else
{
MyHandleError("OpenToDecode failed");
}
下面的过程和Encode类似,调用的函数和上面相同,只不过是过程逆向
printf("/nThe length of the encoded message is %d./n/n",
cbEncodedBlob);
if(CryptMsgUpdate(
hMsg, // Handle to the message
pbEncodedBlob, // Pointer to the encoded BLOB
cbEncodedBlob, // Size of the encoded BLOB
TRUE)) // Last call
{
printf("The encoded BLOB has been added to the message. /n");
}
else
{
MyHandleError("Decode MsgUpdate failed");
}
if(CryptMsgGetParam( CryptMsgGetParam的调用和上面有所不同,这里一共是调用两次,第一次的作用主要是得到消息的大小,第二次是得到消息所在的内存地址
hMsg, 消息句柄
CMSG_CONTENT_PARAM, // Parameter type
0,
NULL, // Address for returned
// information
&cbDecoded)) // Size of the returned
// information
{
printf("The decoded message size is %d. /n", cbDecoded);
}
else
{
MyHandleError("Decode CMSG_CONTENT_PARAM failed");
}
if(pbDecoded = (BYTE *) malloc(cbDecoded))
{
printf("Memory has been allocated for the decoded message./n");
}
else
{
MyHandleError("Decoding memory allocation failed.");
}
if(CryptMsgGetParam(
hMsg, // Handle to the message
CMSG_CONTENT_PARAM, // Parameter type
0, // Index
pbDecoded, // Address for returned
// information
&cbDecoded)) // Size of the returned
// information
{
printf("The message is %s./n",(LPSTR)pbDecoded);
}
else
{
MyHandleError("Decode CMSG_CONTENT_PARAM #2 failed");
}
if(pbEncodedBlob)
free(pbEncodedBlob);
if(pbDecoded)
free(pbDecoded);
if(hMsg)
CryptMsgClose(hMsg);
printf("This program ran to completion without error. /n");
} // End of main
下面我们来看看如何哈希一个对话密钥,这个密钥可以用来对一个消息,文件进行加密。我们依旧从一个程序开始。
#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void MyHandleError(char *s);
void main()
{
//--------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Declare variables.
HCRYPTPROV hCryptProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;
//--------------------------------------------------------------------
// Begin processing.
printf("Process beginning. Creating a session key. /n");
if(CryptAcquireContext( 首先依旧是获取一个缺省的CSP句柄
&hCryptProv,
NULL,
NULL,
PROV_RSA_FULL,
0))
{
printf("CryptAcquireContext complete. /n");
}
else
{
MyHandleError("Acquisition of context failed.");
}
if(CryptCreateHash( 创建一个CALG_MD5算法的HASH对象,这个hash对象用的是MD5算法
hCryptProv, 指定一个CSP句柄
CALG_MD5, 指定算法
0,
0,
&hHash))
{
printf("An empty hash object has been created. /n");
}
else
{
MyHandleError("Error during CryptBeginHash!/n");
}
if(CryptGenKey( 创建密钥
hCryptProv, 传入一个CSP句柄
CALG_RC2, 指明密钥身成所用算法
CRYPT_EXPORTABLE, 说明密钥是可以导出到CSP,用于这个应用程序外的
&hKey))
{
printf("A random session key has been created. /n");
}
else
{
MyHandleError("Error during CryptGenKey!/n");
}
if(CryptHashSessionKey( 对生成的密钥进行hash
hHash,
hKey,
0))
{
printf("The session key has been hashed. /n");
}
else
{
MyHandleError("Error during CryptHashSessionKey!/n");
}
在这里就可以添加代码,用生成的密钥进行加密
if(hHash)
{
if(!(CryptDestroyHash(hHash)))
MyHandleError("Error during CryptDestroyHash");
}
if(hKey)
{
if(!(CryptDestroyKey(hKey)))
MyHandleError("Error during CryptDestroyKey");
}
// Release the CSP.
if(hCryptProv)
{
if(!(CryptReleaseContext(hCryptProv,0)))
MyHandleError("Error during CryptReleaseContext");
}
printf("Create random session key completed without error. /n");
} // end main
附件是DOC文档,希望大家多提宝贵意见
Crypto API 学习笔记三
最新推荐文章于 2024-10-18 23:42:37 发布