对CryptEncrypt/CryptDecrypt中的几个参数的解释

最近使用Microsoft CryptoAPI的过程中,发现了其中两个函数的一些问题,做此笔记。

 

BOOL WINAPI CryptEncrypt(
  HCRYPTKEY hKey,
  HCRYPTHASH hHash,
  BOOL Final,
  DWORD dwFlags,
  BYTE* pbData,
  DWORD* pdwDataLen,
  DWORD dwBufLen
);
需要注意其中的三个参数:
一、BOOL Final
 
 
  
  Final 
 
 
 
 
[in] Boolean value that specifies whether this is the last section in a series being encrypted.
Final is set to TRUE for the last or only block and to FALSE if there are more blocks to be encrypted.
For more information, see Remarks.

说的比较清楚,若只有一个分组的数据需要加密或者为最后一个分组,则Final为TRUE。

二、DWORD* pdwDataLen

pdwDataLen
[in, out] Pointer to a DWORD value that contains the length of the data buffer. Upon input, the DWORD value is set to the number of bytes to be encrypted. Upon return, the DWORD value contains the number of bytes needed to hold the encrypted data.

在输入时,pdwDataLen为需要加密的分组长度,如使用DES对64位数据进行加密,那么输入时

pdwDataLen为8;在输出时,pdwDataLen为保存密文所需要的字节数。

If the buffer allocated for pbData is not large enough to hold the encrypted data, GetLastError returns ERROR_MORE_DATA and stores the required buffer size, in bytes, in the DWORD value pointed to by pdwDataLen.

如果pbData,即需要加密的数据的缓冲区长度不够保存密文所需要的字节数,那么GetLastError返回

ERROR_MORE_DATA,并且pdwDataLen为需要的字节数。所以为了正确的加密,需要将待加密数据的

缓冲区长度设得更长一点,如上例,不妨设为16个字节。

If pbData is NULL, no error is returned, and the function stores the size of the encrypted data, in bytes, in the DWORD value pointed to by pdwDataLen. This lets an application unambiguously determine the correct buffer size.

If a block cipher is used, this data length must be a multiple of the block size unless this is the final section of data to be encrypted and the Final parameter is set to TRUE.

三、DWORD dwBufLen

dwBufLen
[in] DWORD value that specifies the length, in bytes, of the input pbData buffer.

Note that, depending on the algorithm used, the encrypted text can be larger than the original plaintext. In this case, the pbData buffer needs to be large enough to contain the encrypted text and any padding.

As a rule, if a stream cipher is used, the ciphertext is the same size as the plaintext. If a block cipher is used, the ciphertext is up to a block length larger than the plaintext.

表示pbData缓冲区的长度。需要注意的是,取决于所使用的算法,密文的长度可能会大于明文的长度。

 在这种情况下,pbData缓冲区的长度需要足够大以保证可以存储密密文及填充数据。

如果使用流密码,那么密文和明文的长度是相同的;如果使用分组密码,那么密文比明文多一个分组的

长度。

同样,CryptDecrypt的几个参数类似于上面的解释,也需要注意。

The Microsoft Enhanced Cryptographic Provider supports direct encryption with RSA public keys and decryption with RSA private keys. The encryption uses PKCS #1 Type 2 padding . On decryption, this padding is verified. The length of plaintext data that can be encrypted with a call to CryptEncrypt with an RSA key is the length of the key modulus minus eleven bytes. The eleven bytes is the chosen minimum for PKCS #1 padding. The ciphertext is returned in little-endian format.

在使用RSA密钥,调用CryptEncrypt对明文进行加密时,明文的长度最大为模的长度减去11个字节。

另外,还有一个函数的用法:NetGetJoinInformation

需要有如下代码方能正常使用:

#include <lm.h>

#include <lmjoin.h>

#pragma comment(lib,"NetAPI32.lib")

LPWSTR lpServer;

PNETSETUP_JOIN_STATUS buftype;

buftype=new NETSETUP_JOIN_STATUS;

NetGetJoinInformation(NULL,&lpServer,buftype);

if(lpServer!=NULL)

{

     NetApiBufferFree(lpServer);

}

引用buftype时,只需要(*buftype)即可。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
CryptoAPI是Windows平台上的一种加密API,可以用于加密和解密文件。下面是一个简单的示例,演示如何使用CryptoAPI加密和解密文件: 加密文件: ```c++ #include <windows.h> #include <wincrypt.h> #include <stdio.h> #pragma comment(lib, "crypt32.lib") void EncryptFile(LPCWSTR lpszSourceFile, LPCWSTR lpszDestinationFile, LPCWSTR lpszPassword) { HCRYPTPROV hProv = NULL; HCRYPTKEY hKey = NULL; HCRYPTHASH hHash = NULL; DWORD dwLen; DWORD dwCount; BYTE* pbBuffer = NULL; HANDLE hSourceFile = INVALID_HANDLE_VALUE; HANDLE hDestinationFile = INVALID_HANDLE_VALUE; // 打开源文件 hSourceFile = CreateFile( lpszSourceFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (hSourceFile == INVALID_HANDLE_VALUE) { printf("Error: cannot open source file.\n"); goto Exit; } // 创建目标文件 hDestinationFile = CreateFile( lpszDestinationFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if (hDestinationFile == INVALID_HANDLE_VALUE) { printf("Error: cannot create destination file.\n"); goto Exit; } // 获取密码哈希 if (!CryptCreateHash( hProv, CALG_MD5, 0, 0, &hHash)) { printf("Error: cannot create hash.\n"); goto Exit; } if (!CryptHashData( hHash, (BYTE*)lpszPassword, (DWORD)wcslen(lpszPassword) * sizeof(WCHAR), 0)) { printf("Error: cannot hash password.\n"); goto Exit; } // 获取加密密钥 if (!CryptDeriveKey( hProv, CALG_RC4, hHash, 0, &hKey)) { printf("Error: cannot derive key.\n"); goto Exit; } // 加密数据 dwLen = GetFileSize(hSourceFile, NULL); pbBuffer = new BYTE[dwLen]; if (!ReadFile(hSourceFile, pbBuffer, dwLen, &dwCount, NULL)) { printf("Error: cannot read source file.\n"); goto Exit; } if (!CryptEncrypt( hKey, NULL, TRUE, 0, pbBuffer, &dwLen, dwLen)) { printf("Error: cannot encrypt data.\n"); goto Exit; } // 写入加密后的数据到目标文件 if (!WriteFile(hDestinationFile, pbBuffer, dwLen, &dwCount, NULL)) { printf("Error: cannot write destination file.\n"); goto Exit; } Exit: if (hSourceFile != INVALID_HANDLE_VALUE) { CloseHandle(hSourceFile); } if (hDestinationFile != INVALID_HANDLE_VALUE) { CloseHandle(hDestinationFile); } if (hHash != NULL) { CryptDestroyHash(hHash); } if (hKey != NULL) { CryptDestroyKey(hKey); } if (hProv != NULL) { CryptReleaseContext(hProv, 0); } if (pbBuffer != NULL) { delete[] pbBuffer; } } ``` 解密文件: ```c++ #include <windows.h> #include <wincrypt.h> #include <stdio.h> #pragma comment(lib, "crypt32.lib") void DecryptFile(LPCWSTR lpszSourceFile, LPCWSTR lpszDestinationFile, LPCWSTR lpszPassword) { HCRYPTPROV hProv = NULL; HCRYPTKEY hKey = NULL; HCRYPTHASH hHash = NULL; DWORD dwLen; DWORD dwCount; BYTE* pbBuffer = NULL; HANDLE hSourceFile = INVALID_HANDLE_VALUE; HANDLE hDestinationFile = INVALID_HANDLE_VALUE; // 打开源文件 hSourceFile = CreateFile( lpszSourceFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (hSourceFile == INVALID_HANDLE_VALUE) { printf("Error: cannot open source file.\n"); goto Exit; } // 创建目标文件 hDestinationFile = CreateFile( lpszDestinationFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if (hDestinationFile == INVALID_HANDLE_VALUE) { printf("Error: cannot create destination file.\n"); goto Exit; } // 获取密码哈希 if (!CryptCreateHash( hProv, CALG_MD5, 0, 0, &hHash)) { printf("Error: cannot create hash.\n"); goto Exit; } if (!CryptHashData( hHash, (BYTE*)lpszPassword, (DWORD)wcslen(lpszPassword) * sizeof(WCHAR), 0)) { printf("Error: cannot hash password.\n"); goto Exit; } // 获取解密密钥 if (!CryptDeriveKey( hProv, CALG_RC4, hHash, 0, &hKey)) { printf("Error: cannot derive key.\n"); goto Exit; } // 解密数据 dwLen = GetFileSize(hSourceFile, NULL); pbBuffer = new BYTE[dwLen]; if (!ReadFile(hSourceFile, pbBuffer, dwLen, &dwCount, NULL)) { printf("Error: cannot read source file.\n"); goto Exit; } if (!CryptDecrypt( hKey, NULL, TRUE, 0, pbBuffer, &dwLen)) { printf("Error: cannot decrypt data.\n"); goto Exit; } // 写入解密后的数据到目标文件 if (!WriteFile(hDestinationFile, pbBuffer, dwLen, &dwCount, NULL)) { printf("Error: cannot write destination file.\n"); goto Exit; } Exit: if (hSourceFile != INVALID_HANDLE_VALUE) { CloseHandle(hSourceFile); } if (hDestinationFile != INVALID_HANDLE_VALUE) { CloseHandle(hDestinationFile); } if (hHash != NULL) { CryptDestroyHash(hHash); } if (hKey != NULL) { CryptDestroyKey(hKey); } if (hProv != NULL) { CryptReleaseContext(hProv, 0); } if (pbBuffer != NULL) { delete[] pbBuffer; } } ``` 要使用这些功能,只需调用EncryptFile和DecryptFile函数,并传递源文件路径、目标文件路径和加密/解密密码即可。请注意,这只是一个简单的示例,实际应用需要考虑更多的安全问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值