为什么我从WinAPI/Crypt 32 base64 Encoding函数中得到一些奇怪的换行符?

t40tm48m  于 9个月前  发布在  其他
关注(0)|答案(1)|浏览(119)

我有这样一段代码,它应该使用crypt32.dll/WinAPI对字符串进行base64编码:

#include <windows.h>
#include <stdio.h>
int encodeBase64(const char *input, char **output, DWORD *outputSize)
{
    HMODULE hCrypt32 = LoadLibrary("crypt32.dll");
    if (!hCrypt32) {
        return -2;
    }
    typedef BOOL(WINAPI *CryptBinaryToStringFunc)(const BYTE *, DWORD, DWORD, LPSTR, DWORD *);

    CryptBinaryToStringFunc cryptBinaryToString = (CryptBinaryToStringFunc)GetProcAddress(hCrypt32, "CryptBinaryToStringA");
    if (!cryptBinaryToString)
    {
        FreeLibrary(hCrypt32);
        return -3;
    }
    if (!cryptBinaryToString((const BYTE*)input, strlen(input), CRYPT_STRING_BASE64, NULL, outputSize))
    {
        FreeLibrary(hCrypt32);
        return -4;
    }
    *output = (char*)HeapAlloc(GetProcessHeap(), HEAP_NO_SERIALIZE, (*outputSize) * sizeof(char));
    if (!*output)
    {
        FreeLibrary(hCrypt32);
        return -5;
    }
    if (!cryptBinaryToString((const BYTE*)input, strlen(input), CRYPT_STRING_BASE64, *output, outputSize))
    {
        HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, *output);
        FreeLibrary(hCrypt32);
        return -6;
    }
    FreeLibrary(hCrypt32);
    return 0;
}

int main()
{
    LPCSTR pszSource = "Man is distinguished, not only by his reason, but ...";
    char *pszDestination = NULL;
    DWORD nDestinationSize;
    int result = encodeBase64(pszSource, &pszDestination, &nDestinationSize);
    if (result == 0)
    {
        printf("Encoded string: '%s'", pszDestination);
        HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pszDestination);
    }
    else
    {
        printf("Error in Encoding...\n");
    }
    return 0;
}

字符串
输出应为:

Encoded string: 'TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCAuLi4='


但我得到的却是:

Encoded string: 'TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1
dCAuLi4=
'


我的代码中有什么问题吗?我想这是因为base64中有\n,但显然不是,因为我通过使用适当的在线工具确认了这一点。

zqdjd7g9

zqdjd7g91#

我不会声称 * 完全 * 理解为什么1,2,但是,为了删除输出中不需要的换行符,Base64编码的字符串,您可以在dwFlags参数中包含CRYPT_STRING_NOCRLF位(使用按位OR运算符):

int encodeBase64(const char* input, char** output, DWORD* outputSize)
{
    DWORD cryptFlags = CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF; // Modify the flags
    HMODULE hCrypt32 = LoadLibrary("crypt32.dll");
    if (!hCrypt32) {
        return -2;
    }
    typedef BOOL(WINAPI* CryptBinaryToStringFunc)(const BYTE*, DWORD, DWORD, LPSTR, DWORD*);

    CryptBinaryToStringFunc cryptBinaryToString = (CryptBinaryToStringFunc)GetProcAddress(hCrypt32, "CryptBinaryToStringA");
    if (!cryptBinaryToString)
    {
        FreeLibrary(hCrypt32);
        return -3;
    }
    if (!cryptBinaryToString((const BYTE*)input, strlen(input), cryptFlags, NULL, outputSize))
    {
        FreeLibrary(hCrypt32);
        return -4;
    }
    *output = (char*)HeapAlloc(GetProcessHeap(), HEAP_NO_SERIALIZE, (*outputSize) * sizeof(char));
    if (!*output)
    {
        FreeLibrary(hCrypt32);
        return -5;
    }
    if (!cryptBinaryToString((const BYTE*)input, strlen(input), cryptFlags, *output, outputSize))
    {
        HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, *output);
        FreeLibrary(hCrypt32);
        return -6;
    }
    FreeLibrary(hCrypt32);
    return 0;
}

字符串
输出量:

Encoded string: 'TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCAuLi4='


the documentation
HTTP_STRING_NOCRLF(0x 4000000)-不向编码字符串追加任何新行字符。默认行为是使用回车/换行(CR/LF)对(0x 0 D/0x 0A)来表示新行。
1我的主要困惑,在这里,是建议标志的描述指出,该函数将不会追加任何新的行字符;只是如何/为什么适用于防止此类字符 * 内 * 编码字符串我逃避。
2看起来,正如在对this question的回答中提到的,Base64规范允许每76个字符插入一个换行符。现在,微软是什么,他们似乎已经改变了“换行”长度为64个字符,这是你的编码字符串有看似无关的换行符的点。感谢Sa'id Karboutli在评论中指出这一点。

相关问题