【问题标题】:compare two secKey (public keys) in ios Swift在 ios Swift 中比较两个 secKey(公钥)
【发布时间】:2016-01-26 07:54:08
【问题描述】:

我想在 swift 中使用 ssl 公钥固定,我阅读了很多如何做到这一点的示例,最后想我找不到的是如何比较 SecKey 对象格式的两个公钥。 示例:

let serverPublicKey = SecTrustCopyPublicKey(secTrust) /*return SecKey object from actual SecTrust*/
let clientPublicKey = getLocalPublicKeyFromDer() /*return SecKey from .der local*/

如何比较它们?现在我这样做并且它有效:

if(serverPublicKey! as AnyObject).isEqual(clientPublicKey){
  /*Key is the same, pinning OK!*/
}

在 gitHub 上找到它:https://github.com/teamcarma/IOS-AlamofireDomain/blob/master/Source/ServerTrustPolicy.swift

但是转换为 AnyObject 是个好主意吗?如何在强制转换的 SecKey 上使用 isEqual?任何人都可以解释我吗?

ps。 另一个想法是从 SecKey 获取 base64 - 我尝试过,它也可以工作,但它需要 KeyChain 临时操作并且看起来不专业。

【问题讨论】:

标签: ios swift security


【解决方案1】:

引自标题:

“大多数 SecKeychainItem 函数都适用于 SecKeyRef。”*

您可以将SecKeyRef 转换为SecKeychainItem。如果这是一个有效的操作(即密钥是一个钥匙串项),你可以应用函数

SecKeychainItemCreatePersistentReference

并获得一个CFData 对象,其中填充了属性和数据。然后使用memcpy检查字节或将其转换为NSData对象并使用isEqualToData检查。不要忘记释放CFData 对象。

编辑

据我所知,在 iOS 上,唯一可靠的方法是将数据(或秘密)复制到钥匙串中,使用临时密钥,以便您可以再次找到它,然后提取数据。比较麻烦,但是如果只是用极简的方式实现的话,应该不会超过30行代码。我有一个工作示例。

通常的免责声明:使用此功能需要您自担风险,并始终注意安全问题。

【讨论】:

  • 是的,我尝试将一些想法转换为 NSData 并且它与钥匙串一起使用,但在钥匙串上添加和删除 - 对我来说非常难看(基于这张票的最后评论):stackoverflow.com/questions/27758446/…。我不知道 SecKeychainItemCreatePersistentReference。为什么 isEqual 与强制转换的 anyObject 有效? :)
  • @luky0007 您只需要比较CFData 对象中的字节数。你如何做到这一点,并不重要。但是,如果您为了 ARC 将CFData 正确转换为NSData,则只需使用方法isEqualToData。另见:stackoverflow.com/questions/25262542/…
  • 该功能在iOS上不可用。
  • 是的 - 我检查了它仅适用于 OSX。
  • @chedabob @luky0007 是的,这是真的。基本上,您需要使用 SecItemCopyMatching 查询钥匙串或 sec 项目数组并返回匹配的 sec 项目。您可以指定将返回的 sec 项表示为 CFData。不幸的是,这样做“迅速”仍然太麻烦。稍后我会尝试找到一个好的解决方案。
【解决方案2】:

iOS10 新增:

CFDataRef _Nullable SecKeyCopyExternalRepresentation(SecKeyRef key, CFErrorRef *error)

所以您现在可以创建两个 Data (NSData) 对象,然后比较它们。

【讨论】:

    【解决方案3】:

    看看这个答案以获得NSDataCan I get the modulus or exponent from a SecKeyRef object in Swift?

    然后您可以使用isEqualToData: 比较两个NSData 实例

    【讨论】:

    • 我知道它有效,不幸的是它疯狂地四处走动 - 添加到钥匙串,然后从钥匙串中删除仅用于将 SecKey 转换为 NSData,疯狂的苹果 :),为什么没有转换它的功能? SSL Pining 是创建安全应用程序的基本思想... 为什么 if(serverPublicKey! as AnyObject).isEqual(clientPublicKey) 有效???
    【解决方案4】:

    我在该领域没有经验,但如果它们是两个字符串(无论它们的内容如何),你基本上会做一个简单的检查:

    if(string1 == string2)
    {
     //condition logic
    }
    

    【讨论】:

    • SecKey 不是字符串,是对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-02
    • 2015-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-13
    • 2017-12-09
    相关资源
    最近更新 更多