[Swift] 开源我的数据加密用框架 - Keys - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iOS 开发实用技术导航
NSHipster 中文版
http://nshipster.cn/
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
CocoaPods
http://cocoapods.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Design Guides and Resources
https://developer.apple.com/design/
Transcripts of WWDC sessions
http://asciiwwdc.com
Cocoa with Love
http://cocoawithlove.com/
Cocoa Dev Central
http://cocoadevcentral.com/
NSHipster
http://nshipster.com/
Style Guides
Google Objective-C Style Guide
NYTimes Objective-C Style Guide
Useful Tools and Services
Charles Web Debugging Proxy
Smore
remaerd
V2EX    iDev

[Swift] 开源我的数据加密用框架 - Keys

  •  
  •   remaerd
    remaerd 2015-08-13 03:17:23 +08:00 3815 次点击
    这是一个创建于 3715 天前的主题,其中的信息可能已经有所发展或是发生改变。
    https://github.com/remaerd/Keys

    跟大家分享一下我重新的 Swift 数据加密框架 - Keys. 参考了一些 iMessage 和 1Password 的设计原理,将大多数 CommonCrypto 的东西简化掉了。

    希望有朋友能够帮忙看看翻译,懂行的朋友帮忙看看有啥漏洞。

    谢谢了!
    6 条回复    2015-08-13 13:26:21 +08:00
    zhuang
        1
    zhuang  
       2015-08-13 08:34:47 +08:00   2
    Crypto 相关的代码审计是非常专业的工作,这里可能没有人有相关资质,即使有也可能没有精力关注你的个人项目。

    想了解密码学相关的审计工作可以参考 OCAP 对 TrueCypte 做的审计报告。

    https://opencryptoaudit.org/reports/TrueCrypt_Phase_II_NCC_OCAP_final.pdf

    某种意义上说,最不能重复造的轮子就是密码学相关的轮子。





    我简单看了一下你的项目,与 iMessage/1Password 的设计基本无关。二者都是项目意义上的流程设计,而非你实现的密码学方案的设计。

    如果让我来描述你的项目,会是“重新封装的 RSA/AES/SHA 接口,基于 CommonCrypto”。




    算法层面:

    本身是源自 CommonCrypto 的 PBKDF/AES/RSA/SHA 算法,我想没有什么问题。

    实现层面:

    1. 随机化问题:使用 arc4random_uniform() 仅能保证随机分布,String.RandomString() 依赖外部初始化,但没有严格的 RNG(随机数生成器)。这一点几乎可以从密码学意义上判整个实现死刑了。

    2. 数据暴露问题:关键信息的持久化策略,以及关键信息的运行时状态,都可以从外部轻易访问到。在敏感项目上直接使用 CommonCryto 是有原因的,这是因为它不会由于二次封装而造成信息泄漏。

    其它层面:

    请使用密码学术语。



    这仅仅是一个非专业人员花十分钟读了下代码结构发现的问题,如果深入到代码本身上,可能还会有更多问题。



    PS

    作为 CommonCrypto 的 Swift 封装,这个项目还是有意义的。
    remaerd
        2
    remaerd  
    OP
       2015-08-13 10:45:18 +08:00 via iPad
    谢谢 @zhuang 的回复。

    我本身是学设计的,项目需求需要学密码学的东西,很不容易才学到一些东西。所以想提供一些简单的接口,简化使用。开源亦是为了找到像你这样的朋友,对项目的专业性进行评估。

    提到 1Password / iMessage,主要是日后可能会提供一个 Crypto 的 Singleton 让大家直接使用,设计上会参考两者的设计。

    使用非技术词汇去描述项目。主要是想和不懂这些东西的朋友用一种浅显易懂的方式去了解 Crypto,要真的搞明白这些东西还是挺难的。而且 CommonCrypto 本身自带奇葩属性。没有 Diffie-Hellman 的 Header,没有 RSA 接口,要通过 Security 框架下的其它接口实现,非常让人困恼。

    关于数据暴露问题,我的看法是受 1Password 影响的。他直接在互联网上公布技术实现细节,其实不会影响软件的数据泄漏。如果黑客真的攻击成功,这只能是你的软件问题,而不是二次封装导致的问题。

    随机化是我没有学习到的一部分,项目里面可能还会有很多很天真幼稚的实现。希望能够得到你们的指教,我只是起一个头而已。

    多谢了。
    zhuang
        3
    zhuang  
       2015-08-13 11:32:44 +08:00   1
    @remaerd

    数据暴露(Data Exposure)指代的不是开源或者公开设计导致的“实现方法”泄漏,而是指具体的代码实现在使用时的敏感信息,如密钥泄漏。

    密码学意义上有一类叫做 Side-channel attack 的攻击方式,很重要的一环就是根据 Data Remanence 提取敏感信息。

    为什么二次封装会导致数据暴露?

    以 CommonCrypto 或者 libssl(openssl 实现)为例,二者都自己实现了内存分配和回收,所有的密码学运算都是在它自己的内存空间中实现的。其它应用在调用的时候只会通过 IPC 机制获取结果,而不会,同时也不能,获取任何密码学运算的中间状态信息。即使通过 root 权限访问到相应的内存空间,也无法获知其数据结构在内存中的映射方式,因而就保证了不会有数据暴露的问题。

    二次封装 Wrapper 并没有这一机制,当调用 Warpper 的时候,敏感信息在 Wrapper 的内存空间中存在,可以被多种方式获取。
    remaerd
        4
    remaerd  
    OP
       2015-08-13 12:13:56 +08:00
    @zhuang

    感谢解疑。虽然还是一知半解。

    我尝试理解你解说的关于 “自己实现了内存分配和回收” ,是不是相当于使用 alloc malloc release 这些非 ARC 的方式管理内存?当用户输入密码后,因为我不是手动管理内存,所以用户密码会存留在内存里,而且黑客能够通过 root 权限访问这些数据。

    还是举例 1Password 吧?如果用户输入密码,通过 CCKeyDerivationPBKDF 获得密钥后,1Password 会将这个数据缓存在内存里。当设备休眠/锁屏时,敏感数据就会从内存中 nil 掉。

    我的问题是。如果黑客直接用类似 Hooper 这些软件读取你的 App 的数据,而不是获取你的 Wrapper 的数据,那你所说的内存问题还是存在的呀?如果你打开 1Password 查看里面的包,你会发现其实 1Password 里面也有一个类似与 Keys 一样的 Core Framework。你所说的 Side-channel attack,不管用不用 Wrapper,问题还是存在的呀?
    zhuang
        5
    zhuang  
       2015-08-13 12:58:29 +08:00   1
    @remaerd

    Keys 和 1Password 都用了 Core Framework,不代表两者在关键信息的内存管理方式上就是一样的。

    1Password 不一定不存在数据暴露的问题。

    直接使用 CommonCrypto 也可能存在数据暴露的问题,但可能性远远小于二次封装的使用方式。



    内存的分配和回收不是重点,重点是数据在内存中的映射方式。有太多的方式获得内存的 Raw 数据,但这样的数据并没有实际价值,只有在其基础上获得每一块内存的数据定义才有意义。



    比如 Wrapper A 的实现,某个 key 在内存中是连续 32 Bytes 存储的,应用访问它的方式是通过某个指针获得起始内存地址。对于该应用本身而言,它是不关心 key 到底在内存的哪个位置,它只要知道访问它的指针即可。

    对于另一应用 B 来说,如果通过某种手段获得了对 A 内存空间的访问权限,它获取的是某个内存页面的完整信息,但并不知道该 key 到底在哪个地址上。连续 32 Bytes 有太多可能性。



    对于依赖操作系统进行内存管理的应用来说,对于确定的执行流程,数据在内存中的分布有很大可能性是“可预测的”。

    更大的漏洞来源于非人工内存管理带来的多重副本问题。原则上如 key 这样的敏感信息,在内存中应当仅存在一份副本,依赖操作系统对应用内存进行管理时,很可能会造成该 key 在内存中存在多个副本。攻击方寻找一份 32 Bytes 的内容很困难,但是当内存快照中存在多个相同 32 Bytes 连续内容时,提取出该 key 的可能性就非常大了。

    (PBKDF 的白皮书就推荐 pbkdf() 只通过引用传递而不是值拷贝的方式来传入 passphrase,目的是保证敏感信息在内存中只存在一份)


    CommonCrypto/libssl 等底层实现在内存管理上都有特殊之处,就是为了避免当运行时内存被快照化提取后,关键信息不会(轻易)泄漏。理论上内存信息泄漏了,关键信息也随之泄漏了,改变关键信息在内存中分布的目的就是:即使攻击者可以获取内存,也知道关键信息一定在这段内存里,但就是不知道具体哪一部分才是关键信息。
    remaerd
        6
    remaerd  
    OP
       2015-08-13 13:26:21 +08:00
    @zhuang

    感谢回复。真的是非常详细,多谢。

    若是内存管理层面上的,我觉得都不是不能解决的问题。问题肯定是有的,OpenSSL 还有 Heartbleed 呢,但项目还是要做的,因为要用到。总之注意内存管理就好了,或许在 README 中添加一些关于内存管理的文字会是一个好的开始。

    再次感谢。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5632 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 06:31 PVG 14:31 LAX 23:31 JFK 02:31
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86