我正在尝试使用CryptProtectData函数,因此我可以加密我的密码并在我的MAPI配置文件中使用它。我正在使用这两篇文章http://blogs.msdn.com/b/dvespa/archive/2013/05/21/how-to-mfcmapi-create-mapi-profile-exchange-2013.aspx 和http://blogs.msdn.com/b/dvespa/archive/2013/07/15/create-profile-connect-mfcmapi-to-office-365.aspx用于通过MFCMAPI连接到我的托管交换(2013)帐户。设置我的所有属性时,系统会提示我输入我的凭据,并且我遇到了为域提供的字段太短的问题。所以我必须手动设置这些属性(如何在第二篇文章中描述)。
现在我需要在我的MAPI配置文件中设置用户名和密码,似乎我需要自己加密密码(我必须构建一个应用程序来执行此操作)。我正在使用" MAPI下载配置指南.docx" (可以从www .microsoft.com / en-us / download / details.aspx下载?id = 39045我正在使用的代码片段在文档末尾)用于构建我自己的应用程序来加密我的密码(i我使用较小的例子来加密密码,而不是创建整个配置文件)。我有很多问题,应用程序没有在32位Windows上运行,而不是crypt32.lib丢失(我必须自己创建),依此类推。现在我让它在64位机器上运行,但现在我不知道如何将我的数据提供给程序。
我有以下代码:
std::string stemp = "myPassword";
std::wstring stemp1 = std::wstring(stemp.begin(), stemp.end());
LPWSTR pwszPassword = (LPWSTR)stemp1.c_str();//stemp.c_str();//
HRESULT hr = S_OK;
DATA_BLOB dataBlobIn = {0};
DATA_BLOB dataBlobOut = {0};
SPropValue propValues[2] = {0};
// Validate parameters
// Encrypt password based on local user authentication
dataBlobIn.pbData = (LPBYTE)pwszPassword;
// Include NULL character
dataBlobIn.cbData = (::wcslen(pwszPassword) + 1) * sizeof(WCHAR);
CryptProtectData(
&dataBlobIn,
NULL,
NULL,
NULL,
NULL,
0,
&dataBlobOut);
std::cout<<"\n-- ";
std::wcout<<(dataBlobOut.cbData);
std::cout<<" --\n";
std::wcout<<(dataBlobOut.pbData);
现在输出这两个值时,对于dataBlobOut.cbData,我主要得到&#34; 230&#34; (我认为当我改变密码的大小时,这可能会改变,但事实并非如此,它对于密码有相同的价值,例如&#34; aaa&#34;,&#34; bbbbb&#34;,&#34 ; cc&#34; ...),对于dataBlobOut.pbData,我得到一个Hexadezimal值(类似于0x2cde50)我认为它是变量的地址,因为pbData是一个指针。
由于我得到了diffrente密码的完全相同的值,我认为我的方法不对。但是我需要更改以获取加密密码,以便在MAPI配置文件中填写属性PR_PROFILE_AUTH_PASSWORD?
我在微软交流论坛上也提到了这个问题,但我认为他们的论坛比软件开发更注重技术。
亲切的问候 RIMES
答案 0 :(得分:0)
很抱歉,好像我没有用我的正确帐户发布邮件(并且我不能写评论)。
正如我所说,我试图将加密数据输出到文本文件中:
std::ofstream myfile;
myfile.open ("encrypted.txt");
myfile << (LPCWSTR)(dataBlobIn.pbData);
但是当我打开我的.txt时,我会得到类似&#34; 0xca7ee8&#34; (或者在没有(LPCWSTR)的情况下写它时它是空的)。愿这是&#34;对&#34;输出完全?我的意思是我期待更多的字符,但正如伊戈尔所说,当我改变普通密码的大小时,加密密码的大小不会改变,也许这个输出是我需要的? (或者有什么方法可以验证这是加密密码而不是内存中的随机地址)。
编辑:
我想我得到了解决方案。好像我需要以这种方式输出我的数据:
for (unsigned int i=0;i<dataBlobOut.cbData;i++){
myfile<<dataBlobOut.pbData+i;
}
所以我在我的文本文件中获得了很多nonsens数据,但我认为这是我的加密密码。我将检查它并报告它是否有效在我的MAPI配置文件中设置我的(加密)密码。 但我还有一个问题。对于相同的输入,输出总是相同的还是可以改变(因为在运行我的程序时,我有时会得到相同密码的不同输出)?
答案 1 :(得分:0)
您可以使用以下内容:
#include <windows.h>
#include <stdio.h>
#pragma comment(lib, "crypt32")
int main(int argc, char** argv) {
if(argc != 2) {
fprintf(stdout, "usage: cpd <string>\n");
exit(1);
}
const char* u = argv[1];
DATA_BLOB db_i;
db_i.cbData = static_cast<DWORD>(strlen(u));
db_i.pbData = (BYTE*)(u);
DATA_BLOB db_o = {0, NULL};
if(!::CryptProtectData(&db_i,
NULL, NULL, NULL, NULL,
CRYPTPROTECT_UI_FORBIDDEN,
&db_o)) {
fprintf(stdout,
"CryptProtectData failed with error %ld\n",
GetLastError());
}
else {
short nl = 0;
for(DWORD c = 0; c < db_o.cbData; c++) {
if((c % 40) == 0)
fprintf(stdout, "\n");
fprintf(stdout, "%2.2x", db_o.pbData[c]);
}
LocalFree(db_o.pbData);
}
return 0;
}
该字符串被写为十六进制表示(最大行80)。您可以将db_o.pbData格式化为std :: string以进行序列化(有多种方法可以执行此操作 - 我更喜欢为db_o.cbData * 2 + 1分配一个char *,以便为十六进制表示提供2个字符,加上1对于NUL终结符,然后从pbData为每个BYTE顺序写入2个字符。
如果crypt32.lib不可用,您可以使用LoadLibrary / GetProcAddress动态加载函数。