macos - 与 OS X 钥匙串(keychain)关联的不可见文件

标签 macos locking keychain flock security-framework

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

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

  • 它是空的(零字节)。
  • 它的权限是 0444 (所有用户只读)。
  • 它的名称由 .fl 组成后跟 8 个十六进制字符。例如:
    .fl043D1EDD
    .fl947E1BDB
    .fl9FAF0136
    .fl12663120
    .fl8E6EFC6C
    .flCF600F4B
    .fl1D8ECE61
    .fl0D1D1BA9
    .fl79E88CD1
    .fl62323D2F
    .fl75262C83
    .fl652F188E
    

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

    以下是一些演示步骤,使用 Keychain Access公用事业:
  • 创建一个新的钥匙串(keychain),选择 文件 > 新钥匙串(keychain) 并选择一个目录来创建它。将在与新钥匙串(keychain)相同的目录中创建一个不可见文件。
  • 删除不可见文件(使用 Finder 或终端)。
  • 修改钥匙串(keychain)的内容。例如,通过选择 ,向钥匙串(keychain)添加安全注释。文件 > 新建安全笔记项目 .不可见文件将使用相同的名称重新创建。
  • 通过选择 删除钥匙串(keychain)文件 > 删除钥匙串(keychain) > 删除引用和文件 .隐形文件也将被删除。

  • 我已经验证这发生在 OS X 10.810.9 .

    更新

    使用 Apple 的 security 操作钥匙串(keychain)时会创建相同的不可见文件终端中的工具:
  • 创建一个新的钥匙串(keychain)。还会创建一个不可见的文件。
    $ cd ~/Desktop/
    $ ls -1a
    .
    ..
    $ /usr/bin/security create-keychain ~/Desktop/Test.keychain
    $ ls -1a
    .
    ..
    .fl1BCE4B9A
    Test.keychain
    
  • 删除不可见文件。
    $ rm .fl1BCE4B9A
    $ ls -1a
    .
    ..
    Test.keychain
    
  • 修改钥匙串(keychain)的内容(例如:通过添加互联网密码)。使用相同名称重新创建不可见文件。
    $ /usr/bin/security add-internet-password -a account -s google.com -w password ~/Desktop/Test.keychain
    $ ls -1a
    .
    ..
    .fl1BCE4B9A
    Test.keychain
    
  • 删除钥匙串(keychain)。不可见文件也被删除。
    $ /usr/bin/security delete-keychain ~/Desktop/Test.keychain
    $ ls -1a
    .
    ..
    


  • 问题
  • 为什么会创建这些不可见的文件?他们的目的是什么?
  • 什么fl在文件名中是什么意思?
  • 文件名中的 8 个十六进制字符是什么?某种识别钥匙串(keychain)的唯一 ID 或哈希?
  • 有没有办法防止在创建或修改钥匙串(keychain)时创建这些文件?
  • 最佳答案

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

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


  • 以下是我的调查详情:

    钥匙串(keychain)的锁定/解锁状态

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

    系统调用

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

    这些系统调用负责操作不可见文件:
  • 创建新钥匙串(keychain)时创建不可见文件:
  • Security::AtomicFile::create(unsigned short)
  • Security::RefPointer<Security::AtomicLockedFile>::release_internal()
  • Relevant part of the call tree
  • 当钥匙串(keychain)的内容被修改时重新创建不可见文件:
  • Security::AtomicFile::write()
  • Security::RefPointer<Security::AtomicLockedFile>::release_internal()
  • Relevant part of the call tree
  • 删除钥匙串(keychain)时删除不可见文件:
  • Security::AtomicFile::performDelete()
  • Relevant part of the call tree

  • C++文件

    这些是相关的文件和类(可从 Apple Open Source 获得 OS 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()
  • “现在我们持有写锁”
  • AtomicFile::write()
  • “锁定数据库文件进行写入并返回一个新创建的 AtomicTempFile。”
  • AtomicFile::performDelete()
  • “获取写锁并删除文件。”
  • “取消链接我们的锁定文件”

  • 锁定文件名的生成

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

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

    哪里hashSHA-1 的前 4 个字节钥匙串(keychain)文件名的哈希值。

    注意:仅使用 4 个字节(32 位)的散列,有一个 reasonable chance of a hash collision ,这是在 LocalFileLocker::lock() 的评论中提到的.

    锁的操作

    flock() 系统调用用于操作锁文件上的锁。

    这是当钥匙串(keychain)的数据库被锁定以进行写入时的调用树:

    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
    

    关于macos - 与 OS X 钥匙串(keychain)关联的不可见文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24288840/

    相关文章:

    objective-c - NSTableView + NSTextFieldCell 动态行大小

    iOS:存储在安全区域中的 key 不支持解密

    sql - 删除多行而不锁定它们

    java - 印章锁说明。 java

    ios - 在 KeyChainItemWrapper 中保存密码时崩溃

    ios - 如何解决 "entitlement ' keychain-access-groups 具有配置文件不允许的值”

    ios - 使用 NSURLSession 进行单元测试

    database - Delphi XE2中的FireMonkey框架直接支持Mac的哪些数据库?

    objective-c - 带有 bool 参数的 Objective-C 方法中出现奇怪的 "selector mangling"

    C# 和并发读取线程安全对象?