我想编写一个简单的实用程序,用于从Firefox密码数据库中提取密码(相应的文件在配置文件文件夹中称为signons.sqlite
)。
到目前为止我做了什么:使用sqlite打开数据库,检索加密用户名,加密密码和网站地址(全部存储为std::string
)。
因此,唯一剩下的就是解密用户名和密码字符串。
我尝试了以下操作(PK11Decrypt
应将明文密码存储在plaintext
中):
void Firefox_Importer::PK11Decrypt(string _cipheredBuffer, char **plaintext) {
// declarations needed
SECItem * request;
SECItem * reply;
unsigned int len = (unsigned int)_cipheredBuffer.length();
const char* cipheredBuffer = (const char*)_cipheredBuffer.c_str();
// generate request and reply SECItem; seems to work properly
reply = SECITEM_AllocItem(NULL, NULL, 0);
if (reply == NULL) cout << "Error allocating SECITEM." << endl;
request = NSSBase64_DecodeBuffer(NULL, NULL, cipheredBuffer, len);
if (request == NULL) cout << "Error decoding buffer." << endl;
// the following is not working
SECStatus tmp = PK11SDR_Decrypt(request, reply, NULL);
if(tmp != SECSuccess) cout << "Something went wrong during decrypting" << endl;
*plaintext = (char*)malloc(reply->len + 1);
strncpy(*plaintext, (const char*)reply->data, reply->len);
(*plaintext)[reply->len] = '\0';
SECITEM_FreeItem(request, true);
SECITEM_FreeItem(reply, true);
}
调用PK11Decrypt
时,会打印Something went wrong during decrypting
,表示对PK11SDR_Decrypt
的调用无效。它总是返回SECFailure
(对应于-1)。
是否有人提示或知道我做错了什么?
答案 0 :(得分:2)
Firefox是开源软件。您可以找到最新的来源here,由您来找到他们解密密码的部分并将其复制到您的应用程序中。祝你好运。
答案 1 :(得分:2)
可能是PK11_Authenticate()
的调用不是可选的,即使没有设置主密码(是的,NSS非常混乱)。因此,您可能需要先执行以下操作:
PK11SlotInfo *slot = PK11_GetInternalKeySlot();
if (!slot) cout << "Error getting internal slot" << endl;
SECStatus tmp = PK11_Authenticate(slot, PR_TRUE, NULL);
if (tmp != SECSuccess) cout << "Authentication error" << endl;
请注意,我将NULL
作为上下文传递给PK11_Authenticate()
,只有在显示密码提示时才需要上下文。
编辑:没关系,我注意到PK11SDR_Decrypt()
会在内部调用这两个函数。假设您得到SECFailure
,则PK11_GetInternalKeySlot()
可能会失败,这表明NSS未正确初始化。