解密Firefox密码数据库

时间:2011-09-01 17:54:38

标签: c++ firefox encryption

我想编写一个简单的实用程序,用于从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)。

是否有人提示或知道我做错了什么?

2 个答案:

答案 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未正确初始化。