如题,用Windows的CryptoAPI计算MD5我会,但是怎样用CryptoAPI实现DES加密?
自己搞了半天,程序编译没问题,加密得的结果虽然是8字节,但是不对。
对照了MSDN也没看出哪不对,百度、谷歌更是搜不到,有搞过的人能不能指点一下,谢谢!#include <iostream>
#include <Windows.h>
#include <tchar.h>#pragma comment(lib, "Crypt32.lib")int _tmain(int argc, _TCHAR* argv[])
{
BYTE pKey[] = "123";
//BYTE pIV[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};
BYTE pData[256] = "abc";
DWORD dwDataLen = 3; HCRYPTPROV hProv;
if (CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0))
{
HCRYPTHASH hHash;
if (CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
{
CryptHashData(hHash, pKey, sizeof(pKey), 0);
HCRYPTKEY hKey;
if (CryptDeriveKey(hProv, CALG_DES, hHash, 0x00380000, &hKey))
{
//CryptSetKeyParam(hKey, KP_IV, pIV, 0);
CryptEncrypt(hKey, 0, TRUE, 0, pData, &dwDataLen, _countof(pData));
TCHAR szBase64[256];
DWORD dwBase64Len = sizeof(szBase64) / sizeof(szBase64[0]);
CryptBinaryToString(pData, dwDataLen, CRYPT_STRING_BASE64, szBase64, &dwBase64Len);
_tprintf(szBase64);
CryptDestroyKey(hKey);
}
CryptDestroyHash(hHash);
}
CryptReleaseContext(hProv, 0);
}
return 0;
}
自己搞了半天,程序编译没问题,加密得的结果虽然是8字节,但是不对。
对照了MSDN也没看出哪不对,百度、谷歌更是搜不到,有搞过的人能不能指点一下,谢谢!#include <iostream>
#include <Windows.h>
#include <tchar.h>#pragma comment(lib, "Crypt32.lib")int _tmain(int argc, _TCHAR* argv[])
{
BYTE pKey[] = "123";
//BYTE pIV[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};
BYTE pData[256] = "abc";
DWORD dwDataLen = 3; HCRYPTPROV hProv;
if (CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0))
{
HCRYPTHASH hHash;
if (CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
{
CryptHashData(hHash, pKey, sizeof(pKey), 0);
HCRYPTKEY hKey;
if (CryptDeriveKey(hProv, CALG_DES, hHash, 0x00380000, &hKey))
{
//CryptSetKeyParam(hKey, KP_IV, pIV, 0);
CryptEncrypt(hKey, 0, TRUE, 0, pData, &dwDataLen, _countof(pData));
TCHAR szBase64[256];
DWORD dwBase64Len = sizeof(szBase64) / sizeof(szBase64[0]);
CryptBinaryToString(pData, dwDataLen, CRYPT_STRING_BASE64, szBase64, &dwBase64Len);
_tprintf(szBase64);
CryptDestroyKey(hKey);
}
CryptDestroyHash(hHash);
}
CryptReleaseContext(hProv, 0);
}
return 0;
}
解决方案 »
- update更新数据库 求指教
- 如何用钩子修改其他应用程序窗口的控件内容???
- Win 服务程序和一个 Win32 程序通讯,什么方式比较好?
- 请问关于头文件的问题,马上揭贴
- send unicode 的问题
- 文件共享问题,急!
- Why the compiler said that Dlg_OnCopy does not take one paramater ?
- vc ++6.0调用c写的dll的问题。
- 如何用ATL创建一个全局COM(只启动一个实例)供所有客户端使用?
- 请教:如何判断文件是否结束?
- 请问:能不能改变资源里的String Table(字串表)的字体大小
- 两个类可以互相保存对方的指针吗?好像很简单,结果发现好像做不到......大家来帮忙看看
GBool KeyEncryptionAlgorithm::encrypt( Guchar *pdata, Gulong *dataLen, Gulong bufLen, Guchar* key, Gulong keyLen )
{
#ifdef _WIN32
HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hKey = NULL;
GBool ok = gFalse;
Gulong errcode; if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0))
{
return gFalse;
}
if (Algid == CALG_RSA_KEYX)
{
struct {
PUBLICKEYSTRUC hdr;
RSAPUBKEY rsapubkey;
Guchar modulus[130];
} key_blob; key_blob.hdr.bType = PUBLICKEYBLOB;
key_blob.hdr.bVersion = CUR_BLOB_VERSION;
key_blob.hdr.aiKeyAlg = Algid;
key_blob.hdr.reserved = 0;
key_blob.rsapubkey.bitlen = 1024;
key_blob.rsapubkey.magic = 0x31415352;
Guchar *pubkey = key;
if (!IsSequence(*pubkey++))
goto err;
Gulong len1;
pubkey = getLength(pubkey, &len1);
pubkey = getLittleEndianOctetInteger(pubkey, key_blob.modulus, &len1);
getInteger(pubkey, &key_blob.rsapubkey.pubexp);
if (!CryptImportKey(hCryptProv, (Guchar*)&key_blob, sizeof(key_blob), NULL, 0, &hKey))
{
errcode = GetLastError();
goto err;
}
}
else
{
struct {
BLOBHEADER hdr;
Gulong len;
BYTE key[32];
} key_blob; key_blob.hdr.bType = PLAINTEXTKEYBLOB;
key_blob.hdr.bVersion = CUR_BLOB_VERSION;
key_blob.hdr.aiKeyAlg = Algid;
key_blob.hdr.reserved = 0;
key_blob.len = keyLen;
memcpy(key_blob.key, key, keyLen); if (!CryptImportKey(hCryptProv, (BYTE*)&key_blob, sizeof(key_blob), NULL, 0, &hKey))
{
errcode = GetLastError();
goto err;
}
} if (Params)
{
if (Algid == CALG_3DES)
{
if (!CryptSetKeyParam(hKey, KP_IV, Params, 0))
{
errcode = GetLastError();
}
}
}
if(!CryptEncrypt(hKey, NULL, gTrue, 0, pdata, dataLen, bufLen))
{
errcode = GetLastError();
goto err;
}
ok = gTrue;
err:
if(hKey)
CryptDestroyKey(hKey);
if(hCryptProv)
CryptReleaseContext(hCryptProv, 0);
return ok;
#else
return gFalse;
#endif
}
GBool KeyEncryptionAlgorithm::decrypt( Guchar *pdata, Gulong *dataLen, Guchar* key, Gulong keyLen)
{
GBool ok = gFalse;
#ifdef _WIN32
HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hKey = NULL;
Gulong errcode; struct {
BLOBHEADER hdr;
Gulong len;
BYTE key[32];
} key_blob; if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0))
{
return gFalse;
}
key_blob.hdr.bType = PLAINTEXTKEYBLOB;
key_blob.hdr.bVersion = CUR_BLOB_VERSION;
key_blob.hdr.aiKeyAlg = Algid;
key_blob.hdr.reserved = 0;
key_blob.len = keyLen;
memcpy(key_blob.key, key, keyLen);
if (!CryptImportKey(hCryptProv, (BYTE*)&key_blob, sizeof(key_blob), NULL, 0, &hKey))
{
errcode = GetLastError();
goto err;
} if (Params)
{
if (Algid == CALG_3DES)
{
if (!CryptSetKeyParam(hKey, KP_IV, Params, 0))
{
errcode = GetLastError();
}
}
}
// Decrypt data.
if(!CryptDecrypt(hKey, NULL, gTrue, 0, pdata, dataLen))
{
errcode = GetLastError();
goto err;
}
ok = gTrue;
err:
if(hKey)
CryptDestroyKey(hKey);
if(hCryptProv)
CryptReleaseContext(hCryptProv, 0);
#else
#endif
return ok;
}
但是我的代码好像还是得不到正确的结果,能否麻烦帮忙调试一下是哪的问题,再次谢谢
#include <iostream>
#include <Windows.h>
#include <tchar.h>#pragma comment(lib, "Crypt32.lib")int _tmain(int argc, _TCHAR* argv[])
{
struct keyBlob
{
BLOBHEADER hdr;
DWORD cbKeySize;
BYTE rgbKeyData[8];
} keyBlob; keyBlob.hdr.bType = PLAINTEXTKEYBLOB;
keyBlob.hdr.bVersion = CUR_BLOB_VERSION;
keyBlob.hdr.reserved = 0;
keyBlob.hdr.aiKeyAlg = CALG_DES;
keyBlob.cbKeySize = 8;
BYTE Key[8] = {0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31};
CopyMemory(keyBlob.rgbKeyData, Key, keyBlob.cbKeySize); //BYTE pIV[8] = {0x0d, 0x3a, 0x62, 0xdd, 0xfe, 0xcb, 0x2b, 0xba}; BYTE pData[256] = {0x31};
DWORD dwDataLen = 1; HCRYPTPROV hProv;
if (CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0))
{
HCRYPTKEY hKey;
if (CryptImportKey(hProv, (BYTE*)(&keyBlob), sizeof(keyBlob), 0, CRYPT_EXPORTABLE, &hKey))
{
//CryptSetKeyParam(hKey, KP_IV, pIV, 0);
CryptEncrypt(hKey, 0, TRUE, 0, pData, &dwDataLen, _countof(pData));
for (int i = 0; i != dwDataLen; ++i)
_tprintf(_T("%02x "), pData[i]);
_tprintf(_T("\r\n"));
CryptDestroyKey(hKey);
}
CryptReleaseContext(hProv, 0);
}
return 0;
}
但是我4楼帖的程序运行输出的结果却是5c a2 98 19 f0 28 89 40,当然我也试过用密钥11111111来加密数据1(这里的1都直接是数字,也就是0x01,和前面举例的字符串不一样),结果一样不正确。
我的代码哪里有问题?或者能否帖个完整的用CryptoAPI实现DES加密的代码。谢谢了!
一个是PYG密码学综合工具,另一个是Win-Tool之编码转换工具
这两个工具都只用填写密钥和要加密的数据,并不用填写IV向量,但加密出来的结果却是一样的,难道这两个工具里IV是一样的?
是不是标准的DES规定有一个固定的IV值?但是我查了些DES的算法描述,并没有看到有关IV的说明
原来是这样,我以为CryptoAPI会自动补齐后再计算。我对算法不甚了解,感谢你的帮助,差不多可以结贴了,还有最后一个问题,
就是你说的加密结果的长度问题,用密钥“11111111”加密数据“11111111”,上面两个程序得到的结果是8字节的65 5e a6 28 cf 62 58 5f,
但是CryptoAPI得到的却是16字节的65 5e a6 28 cf 62 58 5f 04 5b e2 ac fe 00 f0 c1,前8字节是一样的,但是多出了8字节,尝试了所有加密模式,都是16字节,
这是为何呢?那我该怎么确定最终的加密结果是多少字节?
int _tmain(int argc, _TCHAR* argv[])
{
struct
{
BLOBHEADER hdr;
DWORD cbKeySize;
BYTE rgbKeyData[8];
} keyBlob; keyBlob.hdr.bType = PLAINTEXTKEYBLOB;
keyBlob.hdr.bVersion = CUR_BLOB_VERSION;
keyBlob.hdr.reserved = 0;
keyBlob.hdr.aiKeyAlg = CALG_DES;
keyBlob.cbKeySize = 8;
BYTE Key[8] = {0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31};
CopyMemory(keyBlob.rgbKeyData, Key, keyBlob.cbKeySize); BYTE pData[256] = {0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31};
DWORD dwDataLen = 8; HCRYPTPROV hProv;
if (CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0))
{
HCRYPTKEY hKey;
if (CryptImportKey(hProv, (BYTE*)(&keyBlob), sizeof(keyBlob), 0, 0, &hKey))
{
DWORD dwMode = CRYPT_MODE_CBC;
CryptSetKeyParam(hKey, KP_MODE, (BYTE*)(&dwMode), 0);
CryptEncrypt(hKey, 0, TRUE, 0, pData, &dwDataLen, _countof(pData));
for (int i = 0; i != dwDataLen; ++i)
_tprintf(_T("%02x "), pData[i]);
_tprintf(_T("\r\n"));
CryptDestroyKey(hKey);
}
CryptReleaseContext(hProv, 0);
}
return 0;
}