CryptProtectData:从Crypt32.dll调用MAPI Profile函数的c++代码
CryptProtectData: C++ Code for calling function from Crypt32.dll for MAPI Profile
我试图使用CryptProtectData函数,这样我就可以加密我的密码并在我的MAPI配置文件中使用它。我正在使用这2篇文章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连接到我的托管交换(2013)帐户与MFCMAPI。当设置我的所有属性时,我正在提示我的凭据,并且在那里我遇到了为域提供的字段对我的域太短的问题。所以我必须手动设置这些属性(如何在第二篇文章中描述)。
现在我需要在我的MAPI配置文件中设置用户名和密码,似乎我需要自己加密密码(我必须构建一个应用程序这样做)。我使用"MAPI下载配置指南。docx"(可以从www .microsoft.com/en-us/download/details.aspx?id=39045下载,我使用的代码片段在文档的末尾)构建我自己的应用程序来加密我的密码(我使用较小的示例来加密密码,而不是创建整个配置文件)。我遇到了很多问题,这个应用程序不能在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我大多得到"230"(我认为这可能会改变,当我改变密码的大小,但它没有,它具有相同的值为密码,如"aaa","bbbbb","cc"…),并为dataBlobOut。pbData我得到一个十六进制值(像0x2cde50),我认为这是变量的地址,因为pbData是一个指针。
由于我对不同的密码得到完全相同的值,我认为我的方法是不正确的。但是,我必须更改什么才能获得我的加密密码,以便我可以在我的MAPI配置文件中填写属性PR_PROFILE_AUTH_PASSWORD ?
我在微软交流论坛上也问过这个问题,但我认为他们的论坛更注重技术而不是软件开发。
亲切的问候rim
对不起,我似乎没有用我的正确帐户发布消息(并且我不能写评论)。
正如我所说,我正试图将加密数据输出到文本文件中:
std::ofstream myfile;
myfile.open ("encrypted.txt");
myfile << (LPCWSTR)(dataBlobIn.pbData);
但是当我打开我的。txt时,我只是得到像"0xca7ee8"这样的东西(或者当我在没有(LPCWSTR)的情况下写它时它是空的)。这可能是"正确的"输出吗?我的意思是,我期待更多的字符,但正如Igor所说,加密密码的大小不一定要改变,当我改变普通密码的大小,也许这个输出是我需要的?(或者有什么方法可以让我验证这是加密的密码,而不是内存中的随机地址)
编辑:我想我有办法了。似乎我需要这样输出我的数据:for (unsigned int i=0;i<dataBlobOut.cbData;i++){
myfile<<dataBlobOut.pbData+i;
}
所以我的文本文件中有很多无意义的数据,但我认为这是我的加密密码。我将检查它并报告它是否在我的MAPI配置文件中设置我的(加密)密码有效。但我还有一个担心。对于相同的输入,输出是否总是相同的,或者它也可以改变(因为在运行我的程序时,我有时会为相同的密码得到不同的输出)?
你可以这样写:
#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 %ldn",
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_0。pbData格式化为std::string进行序列化(有多种方法可以做到这一点——我更喜欢为db_o分配一个char*)。cbData * 2 + 1有2个字符用于十六进制表示,加上1为NUL终止符,然后为pbData中的每个字节顺序写入2个字符)。
如果crypt32。
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 代码在main()中运行,但在函数中出现错误
- 内置函数可查看CPP中的成员变量
- 如何获取std::result_of函数的返回类型
- 同时使用Opengl CORE函数以及Comptability Profile - GLFW
- CryptProtectData:从Crypt32.dll调用MAPI Profile函数的c++代码