【发布时间】:2013-10-07 06:58:41
【问题描述】:
我发现 CryptStringToBinary Cryptography API 出现奇怪的行为。
请看下面的代码(配置:x64 Debug):
#include "stdafx.h"
#include <windows.h>
#include <strsafe.h>
#include <iostream>
#include <exception>
void main()
{
DWORD dwSkip;
DWORD dwFlags;
DWORD dwDataLen;
//LPCWSTR pszInput = L"jAAAAAECAAADZgAAAKQAAGdnNL1l56BWGFjDGR3RpxTQqqn6DAw3USv2eMkJYm4t"; //this works fine
LPCWSTR pszInput = L"MyTest"; //doesnt work, API returns false,error code 0x0000000d
// Determine the size of the BYTE array and allocate memory.
if(! CryptStringToBinary(
pszInput,
_tcslen( pszInput ) + 1,
CRYPT_STRING_BASE64,
NULL,
&dwDataLen,
&dwSkip,
&dwFlags ) )
{
DWORD dw = GetLastError(); //0x0000000d: The data is invalid
throw std::exception( "Error computing Byte length." );
}
BYTE *pbyteByte = NULL;
try
{
pbyteByte = new BYTE[ dwDataLen ];
if( !pbyteByte )
{
DWORD m_dwError = ERROR_INVALID_DATA;
throw std::exception( "Wrong array size." );
}
}
catch( std::exception &ex )
{
throw ex;
}
catch(...)
{
throw std::exception( "Out of memory." );
}
return ;
}
对于第一个pszInput 字符串(上面的注释字符串),CryptStringToBinary 返回true。但如果我使用L"MyTest" 作为pszInput 字符串,它会返回false,错误代码为0x0000000。
我知道,传递给 API 的字符串长度存在一些问题。当我传递不带空终止字符 (removed+1) 的长度时,API 总是返回 true。但是在这种情况下,返回的BYTE 长度是否正确?
谁能帮我理解这种行为背后的原因?
另外,我对 API 中长度参数的使用是否正确?
【问题讨论】:
-
CryptStringToBinary cchString(第二个)参数不能包含终止 NULL 字符,所以它必须是 _tcslen( pszInput ) 而不是 _tcslen( pszInput ) + 1 有关详细信息,请参阅msdn.microsoft.com/en-us/library/windows/desktop/aa380285.aspx。
-
Accepted!,但是,我之所以使用+1,是因为WinCrypt.h中使用了CryptStringToBinary函数,上面写着strlen() + 1,见下图: //如果cchString为0,则pszString为NULL终止和 // cchString 是通过 strlen() + 1 获得的。
-
呃,在我开始查看代码之前,这个问题解决了吗?
-
@owlstead:部分问题已解决。我正在使用 CRYPT_STRING_BASE64 编码,并且我正在传递不是 base-64 编码字符串的 L"MyTest"。为此,我认为代码是行为正确的。但是对于我传递为 + 1 的其他部分长度,我不确定是否通过 + 1。您能否提供您在这方面的建议。当我删除长度参数中的 +1 时,为什么 API 对两个输入字符串都有效?谢谢
-
我想这取决于你是否想在明文中包含 \0...
标签: c++ string cryptography