Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Кодирование строки в base64 формат


Автор: Fobos 25.8.2008, 18:29
Пишу программку которая должна отправлять письма, для авторизиции на почтовом сервере логин и паароль необходимо отправлять зашифрованным в base64-алгоритм. В чем собственно проблемка вроде нашел функцию для этого но никак не мгу заставить ее работать. Читал и MSDN там скупо написано, но вроде все правильно, вот код:

Код

CString m_from;
BYTE* buf = new BYTE[200];
DWORD* pcbBinary = new DWORD;
DWORD* pdwSkip = new DWORD;
DWORD* pdwFlags = new DWORD;
ret = CryptStringToBinary((LPCTSTR)m_from, m_from.GetLength(), CRYPT_STRING_BASE64HEADER,
                buf, pcbBinary, pdwSkip, pdwFlags);

эта функция функция выполняется, но код возврата 1, т.е. ошибка. GetLastError() дает 13 ERROR_INVALID_DATA
помогите пожалуйста кто знает в чем проблема

Автор: Fobos 25.8.2008, 19:01
извиняюсь функция возвращает 0 а GetLastError() 13

Автор: vinter 26.8.2008, 09:44
Fobos, так у тя строка пустая, заполни ее чем-нибудь.

Автор: Fobos 26.8.2008, 10:00
Я немного не полностью написал. эта переменная m_from он через DDX получает значение это точно. Прикол в том что если написать вот так, то работать будет
WCHAR* str = L"hello this is a string";

CString m_from;
BYTE* buf = new BYTE[200];
DWORD* pcbBinary = new DWORD;
DWORD* pdwSkip = new DWORD;
DWORD* pdwFlags = new DWORD;
WCHAR* str = L"hello this is a string";
ret = CryptStringToBinary(str, 15, CRYPT_STRING_BASE64,
                buf, pcbBinary, pdwSkip, pdwFlags);
то она работаьт будет. Я смотрел дизассемблером в обоих случаях передается просто адрес строки UNICODE, но работает только во втором. Подскажите в чем проблема.

Автор: vinter 26.8.2008, 10:15
Fobos, в дебаге смотрел что содержится в строке перед вызовом ф-ии? какой размер передается?

Автор: Fobos 26.8.2008, 10:22
Я же написал что проверял Олькой. В обоих случаях в функцию передается адрес строки, по этому адресу реально находится соответствующая строка(проверял). Размер я постоянный выставил. Но в первом случае не работает а во втором случае работает. 
Получаются какие-то чудеса: если адрес строки находится в области где размещаются динамические переменные функция работает, а если адрес строки находится в области где находятся статические переменные то она не работает. Как такое может быть?

Автор: vinter 26.8.2008, 11:08
http://msdn.microsoft.com/en-us/library/aa380285(VS.85).aspx

Автор: Fobos 26.8.2008, 11:18
Да я и MSDN читал, все без толку..

Автор: vinter 26.8.2008, 11:37
Код

CString m_from = _T("превед");
DWORD* pcbBinary = new DWORD;
DWORD* pdwSkip = new DWORD;
DWORD* pdwFlags = new DWORD;

CryptStringToBinary(, m_from.GetLength(), CRYPT_STRING_BASE64HEADER,
                NULL, pcbBinary, pdwSkip, pdwFlags);
BYTE* buf = new BYTE[*pcbBinary];

ret = CryptStringToBinary((LPCTSTR)m_from, m_from.GetLength(), CRYPT_STRING_BASE64HEADER,
                buf, pcbBinary, pdwSkip, pdwFlags);


попробуй так

Автор: Fobos 28.8.2008, 19:16
Не помогает никак  smile 

Автор: blackswanny 13.5.2011, 17:54
аналогичная проблема
поставили задачу перенести ПО с одного сервера на другой, нашёл исходники одной DLL, выяснил, что проблема в CryptStringToBinary, возвращает ERROR_INVALID_DATA, на входе ключ такой же, как и на работающем сервере, в общем всё кажется одинаковым, но что-то не так

Автор: Alca 23.5.2011, 22:14
Цитата

еобходимо отправлять зашифрованным в base64-алгоритм

можно OpenSSL заюзать

Автор: Modul 24.5.2011, 09:37
...и можно найти исходники base64  smile 

Автор: Amp 25.5.2011, 22:38
Эм, алгоритм на коленке реализуется за пол-часа.

Автор: ZVano 12.8.2011, 14:40
У меня отлично работает этот код. Выковырял в нете.
Код

#include <Windows.h>
#include <Wincrypt.h>

#pragma link "crypt32.lib"

DWORD cryptMode = CRYPT_STRING_BASE64;

AnsiString Base64Encode(AnsiString s) {
    DWORD sz;
    AnsiString res;
    CryptBinaryToString((unsigned char*)s.c_str(), s.Length(), cryptMode, NULL, &sz);
    char *r;
    r = (char*)GlobalAlloc(GPTR, sz);
    CryptBinaryToString((unsigned char*)s.c_str(), s.Length(), cryptMode, r, &sz);
    res = AnsiString(r);
    GlobalFree(r);
    res = res.Delete(sz - 1, 2);
    return res;
}

AnsiString Base64Decode(AnsiString s) {
    DWORD sz;
    AnsiString res;

    CryptStringToBinary(s.c_str(), s.Length(), cryptMode, NULL, &sz, NULL, NULL);
    char *r;
    r = (char*)GlobalAlloc(GPTR, sz);
    CryptStringToBinary(s.c_str(), s.Length(), cryptMode, r, &sz, NULL, NULL);
    res = AnsiString(r);
    res.SetLength(sz);
    GlobalFree(r);
    return res;
}


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)