求助:关于VC.Net中数据加密和数字签名的问题(急!!!)

robinzo 2003-07-15 11:12:15
我是头一次做这方面的东西,我的目的是做一个类处理下面的问题,加密给定的字符串,签名给定个文件,而且必须使用vc.net自己的类库,也就是Cryptography API或者ATL类,我按照MSDN中的EncryptFile做了一个加密字串的东西,但是在解密的时候不好用。有没有哪位大哥做过这方面的东西,给我讲一下,或者给我一个例子看看。
...全文
37 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
robinzo 2003-07-16
  • 打赏
  • 举报
回复
是的,例子我也试过的,但是我没有找到一个加密字串的例子,我根据加密文件的例子做的加密字串的程序在解密的时候不对,我想有可能是Key的问题,我把源程序贴上,帮我看看吧
EncryptMessage(LPTSTR szSource,LPTSTR &szDestination, LPTSTR szKey)
{
HCRYPTPROV hCryptProv;
HCRYPTKEY hKey;
HCRYPTHASH hHash;
PBYTE pbBuffer;
DWORD dwBlockLen;
DWORD dwBufferLen;
DWORD dwCount;
//-----------------------------------------------
//Get the handle to the default provider. 取得一个默认Provider的句柄
if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0))
{
return false;
}
//--------------------------------------------------------------------
// Create a hash object.
if(!CryptCreateHash(hCryptProv,CALG_MD5, 0, 0, &hHash))
{
return false;
}
//--------------------------------------------------------------------
// Hash the password.
if(!CryptHashData(hHash, (BYTE *)szKey, (DWORD)strlen(szKey), 0))
{
return false;
}
//--------------------------------------------------------------------
// Derive a session key from the hash object.

if(!CryptDeriveKey(hCryptProv, ENCRYPT_ALGORITHM, hHash, KEYLENGTH, &hKey))
{
return false;
}
//--------------------------------------------------------------------
// Destroy hash object.
if(hHash!= NULL)
{
if(!(CryptDestroyHash(hHash)))
return false;
hHash = 0;
}
//--------------------------------------------------------------------
// The session key is now ready. If it is not a key derived from a
// password, the session key encrypted with the encrypter's private
// key has been returned
// Encrypt data.
dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
//--------------------------------------------------------------------
// Determine the block size. If a block cipher is used,
// it must have room for an extra block.
dwBufferLen = dwBlockLen;
//--------------------------------------------------------------------
// Allocate memory.
if(!(pbBuffer = (BYTE *)malloc(dwBufferLen)))
{
return false;
}
strcpy((char*)pbBuffer,szSource);
dwCount = (DWORD)strlen(szSource);
if(!CryptEncrypt(hKey, 0, true, 0, pbBuffer, &dwCount, dwBufferLen))
{
return false;
}
szDestination = (LPTSTR)pbBuffer;
if(hKey != NULL)
{
if(!(CryptDestroyKey(hKey)))
return false;
}
//--------------------------------------------------------------------
// Release the provider handle.
if(hCryptProv !=NULL)
{
if(!(CryptReleaseContext(hCryptProv, 0)))
return false;
}
return true;
}
DecryptMessage(LPTSTR szSource,LPTSTR &szDestination, LPTSTR szKey)
{
//--------------------------------------------------------------------
// Declare and initialize local variables.
HCRYPTPROV hCryptProv;
HCRYPTKEY hKey;
HCRYPTHASH hHash;
PBYTE pbBuffer;
DWORD dwBlockLen;
DWORD dwBufferLen;
DWORD dwCount;
//--------------------------------------------------------------------
// Get a handle to the default provider.
if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0))
{
return false;
}
//--------------------------------------------------------------------
// Decrypt the file with a session key derived from a password.

//--------------------------------------------------------------------
// Create a hash object.
if(!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash))
{
return false;
}
//--------------------------------------------------------------------
// Hash in the password data.
if(!CryptHashData(hHash, (BYTE *)szKey, (DWORD)strlen(szKey), 0))
{
return false;
}
//--------------------------------------------------------------------
// Derive a session key from the hash object.
if(!CryptDeriveKey(hCryptProv, ENCRYPT_ALGORITHM, hHash, KEYLENGTH, &hKey))
{
return false;
}
//--------------------------------------------------------------------
// Destroy the hash object.
if(!(CryptDestroyHash(hHash)))
return false;
hHash = 0;
//--------------------------------------------------------------------
// The decryption key is now available, either having been imported
// from a BLOB read in from the source file or having been created
// using the password. This point in the program is not reached if
// the decryption key is not available.

//--------------------------------------------------------------------
// Determine the number of bytes to decrypt at a time.
// This must be a multiple of ENCRYPT_BLOCK_SIZE.
dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
dwBufferLen = dwBlockLen;



//--------------------------------------------------------------------
// Allocate memory.
if(!(pbBuffer = (BYTE *)malloc(dwBufferLen)))
{
return false;
}
dwCount = (DWORD)strlen(szSource) + 1;
//--------------------------------------------------------------------
// Decrypt data.
if(!CryptDecrypt(hKey, 0, 1, 0, pbBuffer, &dwCount))
{
return false;
}
//--------------------------------------------------------------------
// Free memory.
if(pbBuffer!=NULL)
free(pbBuffer);
//--------------------------------------------------------------------
// Destroy session key.
if(hKey!= NULL)
{
if(!(CryptDestroyKey(hKey)))
return false;
}
//--------------------------------------------------------------------
// Release provider handle.

if(hCryptProv!=NULL)
{
if(!(CryptReleaseContext(hCryptProv, 0)))
return false;
}
return true;
}
robinzo 2003-07-16
  • 打赏
  • 举报
回复
^_^好用,没想到是这么一个问题,我都急死了,没有好好看程序,还让你帮我改这种错误,不好意思了。以后加密和签名方面的问题可能还要请教你,能不能留个Mail啊?我的是
zoj@vip.sina.com
ahu9870 2003-07-16
  • 打赏
  • 举报
回复
既然你做加密程序,相信密码学的知识都了解了。

MSDN中的大部分例子我都调试过,基本上是正确的。主要问题是按照程序要求设置必要的环境,如建立密钥对及证书。

Cryptography API是对密码学理论的按步就班的引用,比较繁琐;如果你正在学.NET,相对简洁一些。另外,www.codeproject.com 也有一些调试好的例子,虽然代码大一点,但因为不必除错,所以更易理解。
robinzo 2003-07-16
  • 打赏
  • 举报
回复
好的,我试一下,没问题就结贴。^_^这是个测试的类所以没有返回值,直接调试的
ahu9870 2003-07-16
  • 打赏
  • 举报
回复

经过仔细调试,发现了你程序中的两处主要错误(主要体现在解密函数中),经修正后能够还原加密数据,如下:

1。加密后的返回数据为不确定量的数值数据,因此不能用strlen来确定长度,否则会返回错误的大小;
2。在你的解密函数中,没有把形参szSource所传过来的已加密数据复制到pBuffer解密缓冲区中;
3。在你的解密函数中,还原后的数据没有传出来。

我调试所用代码如下,其它问题你自己再找一找吧。

// test.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <windows.h>
#include <wincrypt.h>
#define KEYLENGTH 0x00800000
#define ENCRYPT_ALGORITHM CALG_RC4
#define ENCRYPT_BLOCK_SIZE 8

static int MessageLength = 0; ///////////////////主要修正处

EncryptMessage(LPTSTR szSource,LPTSTR &szDestination, LPTSTR szKey)
{
HCRYPTPROV hCryptProv;
HCRYPTKEY hKey;
HCRYPTHASH hHash;
PBYTE pbBuffer;
DWORD dwBlockLen;
DWORD dwBufferLen;
DWORD dwCount;
//-----------------------------------------------
//Get the handle to the default provider. 取得一个默认Provider的句柄
if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0))
{
return false;
}
//--------------------------------------------------------------------
// Create a hash object.
if(!CryptCreateHash(hCryptProv,CALG_MD5, 0, 0, &hHash))
{
return false;
}
//--------------------------------------------------------------------
// Hash the password.
if(!CryptHashData(hHash, (BYTE *)szKey, (DWORD)strlen(szKey), 0))
{
return false;
}
//--------------------------------------------------------------------
// Derive a session key from the hash object.

if(!CryptDeriveKey(hCryptProv, ENCRYPT_ALGORITHM, hHash, KEYLENGTH, &hKey))
{
return false;
}
//--------------------------------------------------------------------
// Destroy hash object.
if(hHash!= NULL)
{
if(!(CryptDestroyHash(hHash)))
return false;
hHash = 0;
}
//--------------------------------------------------------------------
// The session key is now ready. If it is not a key derived from a
// password, the session key encrypted with the encrypter's private
// key has been returned
// Encrypt data.
dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
//--------------------------------------------------------------------
// Determine the block size. If a block cipher is used,
// it must have room for an extra block.
dwBufferLen = dwBlockLen;
//--------------------------------------------------------------------
// Allocate memory.
if(!(pbBuffer = (BYTE *)malloc(dwBufferLen)))
{
return false;
}
strcpy((char*)pbBuffer,szSource);
dwCount = (DWORD)strlen(szSource);
if(!CryptEncrypt(hKey, 0, true, 0, pbBuffer, &dwCount, dwBufferLen))
{
return false;
}
szDestination = (LPTSTR)pbBuffer;

MessageLength = dwCount; ///////////////////主要修正处

//--------------------------------------------------------
if(hKey != NULL)
{
if(!(CryptDestroyKey(hKey)))
return false;
}
//--------------------------------------------------------------------
// Release the provider handle.
if(hCryptProv !=NULL)
{
if(!(CryptReleaseContext(hCryptProv, 0)))
return false;
}
return true;
}
DecryptMessage(LPTSTR szSource,LPTSTR &szDestination, LPTSTR szKey)
{
//--------------------------------------------------------------------
// Declare and initialize local variables.
HCRYPTPROV hCryptProv;
HCRYPTKEY hKey;
HCRYPTHASH hHash;
PBYTE pbBuffer;
DWORD dwBlockLen;
DWORD dwBufferLen;
DWORD dwCount;
//--------------------------------------------------------------------
// Get a handle to the default provider.
if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0))
{
return false;
}
//--------------------------------------------------------------------
// Decrypt the file with a session key derived from a password.

//--------------------------------------------------------------------
// Create a hash object.
if(!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash))
{
return false;
}
//--------------------------------------------------------------------
// Hash in the password data.
if(!CryptHashData(hHash, (BYTE *)szKey, (DWORD)strlen(szKey), 0))
{
return false;
}
//--------------------------------------------------------------------
// Derive a session key from the hash object.
if(!CryptDeriveKey(hCryptProv, ENCRYPT_ALGORITHM, hHash, KEYLENGTH, &hKey))
{
return false;
}
//--------------------------------------------------------------------
// Destroy the hash object.
if(!(CryptDestroyHash(hHash)))
return false;
hHash = 0;
//--------------------------------------------------------------------
// The decryption key is now available, either having been imported
// from a BLOB read in from the source file or having been created
// using the password. This point in the program is not reached if
// the decryption key is not available.

//--------------------------------------------------------------------
// Determine the number of bytes to decrypt at a time.
// This must be a multiple of ENCRYPT_BLOCK_SIZE.
dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
dwBufferLen = dwBlockLen;



//--------------------------------------------------------------------
// Allocate memory.
if(!(pbBuffer = (BYTE *)malloc(dwBufferLen)))
{
return false;
}
memcpy(pbBuffer, szSource, dwBufferLen); ///////////////////主要修正处

//dwCount = (DWORD)strlen(szSource) + 1;
dwCount = MessageLength; ///////////////////主要修正处

//--------------------------------------------------------------------
// Decrypt data.
if(!CryptDecrypt(hKey, 0, true, 0, pbBuffer, &dwCount))
{
return false;
}

szDestination = (LPTSTR)pbBuffer; ///////////////////主要修正处
//--------------------------------------------------------------------
// Free memory.
//if(pbBuffer!=NULL) ///////////////////主要修正处
// free(pbBuffer);
//--------------------------------------------------------------------
// Destroy session key.
if(hKey!= NULL)
{
if(!(CryptDestroyKey(hKey)))
return false;
}
//--------------------------------------------------------------------
// Release provider handle.

if(hCryptProv!=NULL)
{
if(!(CryptReleaseContext(hCryptProv, 0)))
return false;
}
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
LPTSTR szSource = "This is a test.This is a test.This is a test.This is a test.This is a test.This is a test.";
LPTSTR szDestination = NULL;LPTSTR szRes = NULL;
LPTSTR szKey = "My own password for this test.";
EncryptMessage(szSource, szDestination, szKey);
DecryptMessage(szDestination, szRes, szKey);

// Free memory.
if(szDestination!=NULL) ///////////////////主要修正处
free(szDestination);
if(szRes!=NULL) ///////////////////主要修正处
free(szRes);

return 0;
}

7,540

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 VC.NET
社区管理员
  • VC.NET社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧