与OS X钥匙串关联的不可见文件

时间:2014-06-18 14:57:20

标签: macos locking keychain flock security-framework

似乎keychain文件(扩展名为.keychain)通常会有一个与之关联的不可见文件,位于同一目录中。

这个不可见的文件总是具有以下属性:

  • 它是空的(零字节)。
  • 其权限为0444(对所有用户都是只读的)。
  • 其名称由.fl后跟8个十六进制字符组成。例如:

    .fl043D1EDD
    .fl947E1BDB
    .fl9FAF0136
    .fl12663120
    .fl8E6EFC6C
    .flCF600F4B
    .fl1D8ECE61
    .fl0D1D1BA9
    .fl79E88CD1
    .fl62323D2F
    .fl75262C83
    .fl652F188E
    

可以删除不可见的文件,但是当下次修改了钥匙串的内容时,将使用相同的名称重新创建不可见的文件。

以下是使用Keychain Access实用程序演示的一些步骤:

  1. 选择文件>创建新的钥匙串。新钥匙串并选择要在其中创建它的目录。将在与新密钥链相同的目录中创建一个不可见的文件。
  2. 删除不可见文件(使用Finder或终端)。
  3. 修改钥匙串的内容。例如,通过选择文件>为钥匙串添加安全注释。新的安全注释项。将使用相同的名称重新创建不可见文件。
  4. 选择文件>删除钥匙串。删除钥匙串>删除参考文献&文件即可。隐藏文件也将被删除。
  5. 我已经在OS X 10.810.9中验证了这种情况。


    更新

    使用终端中的Apple security工具操作钥匙串时会创建相同的不可见文件:

    1. 创建一个新的钥匙串。还会创建一个不可见的文件。

      $ cd ~/Desktop/
      $ ls -1a
      .
      ..
      $ /usr/bin/security create-keychain ~/Desktop/Test.keychain
      $ ls -1a
      .
      ..
      .fl1BCE4B9A
      Test.keychain
      
    2. 删除不可见的文件。

      $ rm .fl1BCE4B9A
      $ ls -1a
      .
      ..
      Test.keychain
      
    3. 修改钥匙串的内容(例如:添加互联网密码)。使用相同的名称重新创建不可见文件。

      $ /usr/bin/security add-internet-password -a account -s google.com -w password ~/Desktop/Test.keychain
      $ ls -1a
      .
      ..
      .fl1BCE4B9A
      Test.keychain
      
    4. 删除钥匙串。隐藏文件也会被删除。

      $ /usr/bin/security delete-keychain ~/Desktop/Test.keychain
      $ ls -1a
      .
      ..
      

    5. 问题

      1. 为什么要创建这些不可见的文件?他们的目的是什么?
      2. fl在文件名中的含义是什么?
      3. 文件名中的8个十六进制字符是什么?某种识别钥匙串的唯一ID或哈希?
      4. 有没有办法阻止在创建或修改钥匙串时创建这些文件?

1 个答案:

答案 0 :(得分:8)

经过大量调查后,我设法回答了我的大部分问题:

  1. 隐身文件为钥匙串数据库实现了write lock
  2. .fl是安全框架中AtomicFile类创建的锁文件的文件名前缀。
  3. 文件名中的8个十六进制字符是钥匙串文件名的SHA-1哈希的开头。例如,如果密钥链文件名为Test.keychain,则其文件名的SHA-1哈希值以1BCE4B9A...开头,因此锁定文件将被称为.fl1BCE4B9A
  4. 我还没有找到一种方法来防止在创建或修改钥匙串时创建锁文件。我认为这可能是不可能的,但如果有人能找到办法,我会非常感兴趣

  5. 以下是我调查的详细信息:

    钥匙串的锁定/解锁状态

    我注意到隐身文件受到钥匙串的locked / unlocked状态的影响。如果删除了不可见文件,则锁定/解锁钥匙串会使重新创建不可见文件。

    系统调用

    我使用Apple的Instruments工具中的文件活动模板进行了一些调查。

    这些系统调用负责操作不可见文件:

    • 创建新钥匙串时创建不可见文件:
    • 修改钥匙串内容时重新创建不可见文件:
    • 删除钥匙串时删除不可见文件:

    C ++文件

    这些是相关的文件和类(Apple Open SourceOS X 10.9.2提供的源代码):

    • AtomicFile.cpp
      • Security::AtomicFile
      • Security::AtomicLockedFile
      • Security::AtomicTempFile
      • Security::LocalFileLocker
    • AppleDatabase.cpp
      • Security::AppleDatabase
      • Security::DbModifier

    源代码中的注释

    这些文件中的评论提供了一些线索:

    • AtomicFile::AtomicFile()
      • "计算此文件"
      • 的锁定文件的名称
    • AtomicFile::create()
      • "锁定文件以进行写入并返回新创建的AtomicTempFile。"
      • "现在我们已经创建了锁,而新的db文件创建了一个临时文件对象。"
    • LocalFileLocker::lock()
      • "如果锁定文件不存在,请创建它"
      • "尝试独占访问文件"
      • "检查并查看我们有权访问的文件是否仍然存在。如果没有,另一个文件由于哈希冲突而共享我们的文件锁,并且已经把我们锁定了 - 或者用户将锁文件自己吹走了。"
    • DbModifier::modifyDatabase()
      • "现在我们持有写锁#34;
    • AtomicFile::write()
      • "锁定数据库文件以进行写入并返回新创建的AtomicTempFile。"
    • AtomicFile::performDelete()
      • "获取写锁并删除文件。"
      • "取消关联我们的锁定文件"

    生成锁定文件的名称

    我在AtomicFile构造函数中找到了这段代码:

    char buffer[256];
    sprintf(buffer, "%08X", hash);
    mLockFilePath = mDir + ".fl" + buffer;
    

    其中hash是钥匙串文件名的SHA-1哈希的前4个字节。

    注意:只使用散列的4个字节(32位),reasonable chance of a hash collisionflock()LocalFileLocker::lock()中的注释中提到了这一点。

    锁定操作

    {{3}}系统调用用于操纵锁定文件的锁定。

    以下是锁定钥匙串数据库时的调用树:

    DbModifier::createDatabase() or ::modifyDatabase() or ::deleteDatabase()
      AtomicFile::create() or ::write() or ::performDelete()
        AtomicLockedFile::lock()
          LocalFileLocker::lock()
            flock(mLockFile, LOCK_EX)  // exclusive lock
    

    在写完后解锁时:

    DbModifier::commit()
      AtomicTempFile::commit()
        RefPointer<AtomicLockedFile>::setPointer(AtomicLockedFile*)
          RefPointer<AtomicLockedFile>::release_internal()
            AtomicLockedFile::~AtomicLockedFile()  // destructor
              AtomicLockedFile::unlock()
                LocalFileLocker::unlock()
                  flock(mLockFile, LOCK_UN)  // unlock