`

使用 CryptoAPI 加密(源代码)

    博客分类:
  • VC
阅读更多

#include "stdafx.h"
#include <Windows.h>
#include <WinCrypt.h>
#include <stdio.h>
#include <iostream>
using namespace std;
//确定使用RC2块编码或是RC4流式编码
#ifdef USE_BLOCK_CIPHER
#define ENCRYPT_ALGORITHM	CALG_RC2
#define ENCRYPT_BLOCK_SIZE	8
#else
#define ENCRYPT_ALGORITHM	CALG_RC4
#define ENCRYPT_BLOCK_SIZE	1
#endif
const char* g_szDst = "./dst.txt";
BOOL EncryptWord(LPCTSTR lpszSrc, LPTSTR lpszDst, LPCTSTR lpszPwd);
BOOL DecryptWord(LPCTSTR lpszSrc, LPTSTR lpszDst, LPCTSTR lpszPwd);
int main()
{
	TCHAR szSrc[MAX_PATH] = {0};
	TCHAR szDst[MAX_PATH] = {0};
	TCHAR szPwd[MAX_PATH] = {0};
	TCHAR szVal[MAX_PATH] = {0};
	cout << "please input encrypt string:" << endl;
	cin >> szSrc;
	cout << "enter pwd:" << endl;
	cin >> szPwd;
    
    EncryptWord(szSrc, szDst, szPwd);
	cout << "encrypt dst word:" << endl;
	cout << szDst << endl;
	DecryptWord(szDst, szVal, szPwd);
	cout << "decrypt word:" << endl;
	cout << szVal << endl;
	return 0;
}
BOOL EncryptWord(LPCTSTR lpszSrc, LPTSTR lpszDst, LPCTSTR lpszPwd)
{
	HCRYPTPROV	hProv	= NULL;
	HCRYPTKEY	hKey	= NULL;
	HCRYPTKEY	hChgKey	= NULL;
	HCRYPTHASH	hHash	= NULL;
	DWORD dwKeyBlobLen	= 0;
	PBYTE pbKeyBlob		= NULL;
	//连接缺省的CSP
	CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0);
	if (NULL == lpszPwd)//口令为空,使用随机产生的会话密钥加密
	{		
		//产生随机会话密钥
		CryptGenKey(hProv, ENCRYPT_ALGORITHM, CRYPT_EXPORTABLE, &hKey);
		//取得密钥交换对的公共密钥
		CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hChgKey);
		//计算隐码长度并分配缓冲区
		CryptExportKey(hKey, hChgKey, SIMPLEBLOB, 0, NULL, &dwKeyBlobLen);
		pbKeyBlob = (PBYTE)new char[dwKeyBlobLen + 1];
		CryptExportKey(hKey, hChgKey, SIMPLEBLOB, 0, pbKeyBlob, &dwKeyBlobLen);
		//释放密钥交换对的句柄
		CryptDestroyKey(hChgKey);
		hChgKey = NULL;
		FILE* fp = fopen(g_szDst, "wb");
		fwrite(&dwKeyBlobLen, sizeof(DWORD), 1, fp);
		fwrite(pbKeyBlob, 1, dwKeyBlobLen, fp);
        fclose(fp);
	}
	else //口令不为空,使用从口令派生出的密钥加密文件
	{
		CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
		//建立散列表
		CryptHashData(hHash, (const LPBYTE)lpszPwd, strlen(lpszPwd), 0);
		//散列口令,从散列表中派生密钥
		CryptDeriveKey(hProv, ENCRYPT_ALGORITHM, hHash, 0, &hKey);
		//删除散列表
		CryptDestroyKey(hHash);
		hHash = 0;
	}
	//计算一次加密的数据字节数,必须为ENCRYPT_BLOCK_SIZE的整数倍
	DWORD dwBlockLen = MAX_PATH - MAX_PATH % ENCRYPT_BLOCK_SIZE;
	DWORD dwBufLen = dwBlockLen;
	//如果使用块编码,则需要额外空间
	if (ENCRYPT_BLOCK_SIZE > 1)
	{
		dwBufLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;
	}
	
	//分配缓冲区
	strcpy(lpszDst, lpszSrc);
	CryptEncrypt(hKey, 0, TRUE, 0, (LPBYTE)lpszDst, &dwBlockLen, dwBufLen);
	return TRUE;
}
BOOL DecryptWord(LPCTSTR lpszSrc, LPTSTR lpszDst, LPCTSTR lpszPwd)
{
	HCRYPTPROV	hProv	= NULL;
	HCRYPTKEY	hKey	= NULL;
	HCRYPTKEY	hChgKey	= NULL;
	HCRYPTHASH	hHash	= NULL;
	DWORD dwKeyBlobLen	= 0;
	PBYTE pbKeyBlob		= NULL;
	CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0);
	if (NULL == lpszPwd)
	{
		//口令为空,使用存储在加密文件中的会话密钥解密
		//读隐码的长度并分配内存
		FILE* fp = fopen(g_szDst, "rb");
		fread(&dwKeyBlobLen, sizeof(DWORD), 1, fp);
		fread(pbKeyBlob, 1, dwKeyBlobLen, fp);
		fclose(fp);
		CryptImportKey(hProv, pbKeyBlob, dwKeyBlobLen, 0, 0, &hKey);
	}
	else
	{
		//口令不为空, 使用从口令派生出的密钥解密文件
		CryptCreateHash(hProv, CALG_MD5, NULL, 0, &hHash);
		CryptHashData(hHash, (const LPBYTE)lpszPwd, strlen(lpszPwd), 0);
		CryptDeriveKey(hProv, ENCRYPT_ALGORITHM, hHash, 0, &hKey);
		CryptDestroyHash(hHash);
		hHash = NULL;
	}
	//计算一次加密的数据字节数,必须为ENCRYPT_BLOCK_SIZE的整数倍
	DWORD dwBlockLen = MAX_PATH - MAX_PATH % ENCRYPT_BLOCK_SIZE;
	DWORD dwBufLen = dwBlockLen;
	//如果使用块编码,则需要额外空间
	if (ENCRYPT_BLOCK_SIZE > 1)
	{
		dwBufLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;
	}
	strcpy(lpszDst, lpszSrc);
	CryptDecrypt(hKey, 0, TRUE, 0, (LPBYTE)lpszDst, &dwBlockLen);
	
	return TRUE;
}
 
分享到:
评论

相关推荐

    Microsoft CryptoAPI加密技术 源代码.zip

    这个压缩包包含了与CryptoAPI相关的源代码,可以帮助我们深入理解其工作原理和使用方法。 1. **加密例程.cpp**: 这个源文件可能包含用于执行加密操作的函数和类。CryptoAPI支持多种加密算法,如RSA、DES、3DES、...

    CryptoAPI例子代码

    这个例子代码是一个使用CryptoAPI进行加密和解密的VC6.0工程,它能帮助开发者理解如何在Windows环境中集成加密功能。 在深入讨论CryptoAPI之前,我们先来了解一下加密的基本概念。加密是一种将原始数据(明文)转化...

    crypto_cryptoapi.rar_CRYPTO_Crypto++_cryptoAPI

    这个压缩包包含了一个名为“crypto_cryptoapi.c”的源代码文件,这可能是一个实现接口的示例或核心功能的实现。 CryptoAPI是微软Windows操作系统内核的一部分,提供了一系列接口,使得开发者能够集成加密功能到他们...

    信息安全实验:利用Windows CryptoAPI开发加解密工具软件2

    通过分析源代码,我们可以学习到如何调用CryptoAPI接口,以及如何设计和实现一个用户友好的加密解密应用程序。 在实际开发中,我们需要考虑以下几个方面来确保工具软件的安全性和效率: - **错误处理**:良好的...

    CryptoAPI2_Encrypt_zip_

    【标题】"CryptoAPI2_Encrypt_zip_" 涉及的是使用CryptoAPI(加密应用程序编程接口)对ZIP文件进行加密的技术。CryptoAPI是Windows操作系统提供的一组服务,用于实现密码学功能,包括加密、解密、哈希和数字签名等。...

    CryptoAPI证书操作函数

    在实际开发中,了解并熟练使用CryptoAPI对于创建安全的Windows应用程序至关重要,这包括数据加密、数字签名、密钥管理等多个方面。正确使用CryptoAPI可以确保应用的安全性,防止数据被篡改或伪造,同时也能符合相关...

    CAPI Cypher FASM_cryptoAPI_Encrypt_Asm_

    描述中的 "Microsoft CryptoAPI (CAPI) encryption sample written in flat assembler" 提示我们,这个压缩包中可能包含了一个用汇编语言编写的源代码示例,演示如何利用CryptoAPI进行加密操作。汇编语言是一种低级...

    Laravel开发-cryptoapi

    如果 `cryptoapi` 是一个自定义库,你需要将其源代码添加到项目的 `vendor` 目录,或者发布到 Packagist 并通过 `composer require` 命令安装。如果是一个第三方服务,可能需要注册并获取 API 密钥。 2. **配置加密...

    文件加密源代码

    在Android中,可以使用Java Cryptography Extension (JCE) 库中的`javax.crypto.Cipher`类来实现AES加密。你需要创建一个密钥,然后使用`Cipher.init()`方法初始化,接着调用`Cipher.doFinal()`进行加密和解密操作。...

    AES加密源代码

    总的来说,掌握AES加密源代码的开发和应用,不仅可以增强软件的安全性,也能提升开发者在信息安全领域的专业素养。通过学习和实践,你可以了解到如何在实际项目中实现AES加密,如何设计安全的加密流程,以及如何处理...

    一个简单的MFC类,用于使用Crypto API加密数据

    在`Example.zip`和`crypto.zip`中,可能包含了文章的源代码示例,演示了如何在MFC项目中集成这些步骤。阅读这些代码能帮助你更好地理解如何在实际项目中应用这个简单的MFC加密类。需要注意的是,安全编码原则至关...

    Encrypting and decrypting sensitive data using CryptoAPI. (6

    通常,这样的文件包含一个或多个源代码文件,用于演示如何使用CryptoAPI进行加解密操作。 从压缩包的文件列表来看: 1. `Encrypt.frm`:这很可能是Visual Basic的一个表单文件,用于显示用户界面,可能包括输入...

    网络通信加密程序

    使用CryptoAPI进行对称加密时,首先需要生成一个随机密钥,然后用这个密钥对信息进行加密,最后在接收端使用相同的密钥解密信息。这个过程确保了只有拥有正确密钥的人才能解密信息,从而保证了数据的私密性。 非...

    CAPI Decypher FASM_decryption_cryptoAPI_Asm_

    在描述中提到的"Microsoft CryptoAPI (CAPI) usage sample for decryption in flat assembler",意味着这个压缩包可能包含了一个或多个源代码文件,展示了如何在FASM汇编程序中调用和利用CAPI进行解密操作。...

    加密 解密 源程序 源代码 BCB 示例 范例 MD5 C++Builder

    例如,可以使用CryptoAPI、OpenSSL等库来实现加解密和MD5计算。开发者可以直接调用这些库中的函数,无需从零开始编写加密算法。 在压缩包中,"crypt"这个文件名可能是加密模块的名称,它可能包含了一个或多个源文件...

    Node.js-node-crypto-api提供一个API来消费来自多个加密货币市场的数据

    `node-crypto-api-master` 压缩包很可能包含了该模块的源代码,这可以帮助你深入了解其工作原理,进行自定义扩展或调试。通常,源代码会包含一个 `index.js` 文件作为主入口,以及相关的配置文件、测试用例和其他...

    iOS、Android 双平台AES128加密源代码

    在提供的文件中,"iOS_AES_128"和"Android_AES_128"很可能是两个单独的实现,分别对应iOS和Android平台的AES128加密源代码。开发者可以参考这些源码来理解和实现跨平台的加密解密功能。不过,需要注意的是,为了增强...

    用VC编写文件加密程序的源代码.rar_vc给文件加密_xml_加密_文件加密 VC_文件加密 Visual c++

    例如,使用AES加密时,可以使用 CryptoAPI 或者第三方库如OpenSSL。 4. **写入文件**:将加密后的数据写回磁盘,通常会生成一个新的加密文件。 5. **解密过程**:与加密相反,使用相同的密钥对加密文件进行解密,...

    用vc++实现文件加密功能的源代码

    3. **加密过程**:调用CryptoAPI中的` CryptAcquireContext`函数获取加密上下文,然后使用` CryptGenKey`生成AES密钥,` CryptDeriveKey`根据密钥和IV创建加密对象。最后,使用` CryptEncrypt`函数对缓冲区中的数据...

    Ccryptoapi教程

    在提供的Ccryptoapi教程及实现源代码中,你将看到如何在C++程序中调用上述的CryptoAPI函数,进行实际的加密、解密、签名、验证和哈希计算。通过分析和运行这些示例,你可以更深入地理解CryptoAPI的用法和工作原理。 ...

Global site tag (gtag.js) - Google Analytics