【问题标题】:CryptStringToBinary API behaviorCryptStringToBinary API 行为
【发布时间】: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


【解决方案1】:

您需要输入一个由标志 CRYPT_STRING_BASE64 定义的 base64 字符串 并且 L"MyTest" 不是 base64 而第一个字符串是。

输入格式示例: http://pkix2.sysadmins.lv/library/html/T_PKI_ManagedAPI_CryptEncoding.htm

【讨论】:

  • 您能详细说明一下您的答案吗?
  • CryptStringToBinary( pszInput, /*input 需要采用 flag CRYPT_STRING_BASE64 定义的格式 / _tcslen( pszInput ), / 这是字符串的长度,不需要添加+ 1*/ CRYPT_STRING_BASE64, NULL, &dwDataLen, &dwSkip, &dwFlags)
  • 点评来源: 请EDIT 您的答案并将这些详细信息添加到其中。请避免评论您自己的答案。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-10
  • 2020-04-19
  • 2016-01-03
  • 2019-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多