【问题标题】:Elliptic Curve Diffie Hellman in ios/swiftios/swift 中的椭圆曲线 Diffie Hellman
【发布时间】:2017-09-19 13:01:01
【问题描述】:

iOS 是否公开 API 用于生成密钥和使用 ECDH 导出密钥?

据我所见,Apple 正在内部使用它(特别是 x25519),但我不认为它通过通用加密或其他方式公开为公共 API。

谢谢,

Z

【问题讨论】:

  • 你看过SecKeyCopyKeyExchangeResult吗?
  • @Mats 谢谢 - 我做到了,而且看起来很相关,但不幸的是,文档是如此糟糕和神秘,以至于很难说出如何使用它以及它是否符合我的要求。
  • SecKey.h 头文件可能包含一些在线文档中没有的附加信息。
  • @Mats 我明白了。最后。感谢您的帮助。
  • 如果您有时间,请考虑为您的问题写一个更详细的答案。它可以是一个演示如何使用 API 的小代码示例。

标签: ios swift cryptography elliptic-curve ecdh


【解决方案1】:

使用 Xcode 8.3.3 在操场上完成,使用 EC 为 Alice、Bob 生成一个私钥/公钥,然后使用 Alice 的私钥和 Bob 的公钥计算 Alice 的共享密钥,并使用 Bob 的私钥和 Alice 的公钥为 Bob 共享密钥最后断言他们是平等的。

import Security
import UIKit

let attributes: [String: Any] =
    [kSecAttrKeySizeInBits as String:      256,
     kSecAttrKeyType as String: kSecAttrKeyTypeEC,
     kSecPrivateKeyAttrs as String:
        [kSecAttrIsPermanent as String:    false]
]

var error: Unmanaged<CFError>?
if #available(iOS 10.0, *) {
    // generate a key for alice
    guard let privateKey1 = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
        throw error!.takeRetainedValue() as Error
    }
    let publicKey1 = SecKeyCopyPublicKey(privateKey1)

    // generate a key for bob
    guard let privateKey2 = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
        throw error!.takeRetainedValue() as Error
    }
    let publicKey2 = SecKeyCopyPublicKey(privateKey2)

    let dict: [String: Any] = [:]

    // alice is calculating the shared secret
    guard let shared1 = SecKeyCopyKeyExchangeResult(privateKey1, SecKeyAlgorithm.ecdhKeyExchangeStandardX963SHA256, publicKey2!, dict as     CFDictionary, &error) else {
        throw error!.takeRetainedValue() as Error
    }

    // bob is calculating the shared secret
    guard let shared2 = SecKeyCopyKeyExchangeResult(privateKey2, SecKeyAlgorithm.ecdhKeyExchangeStandardX963SHA256, publicKey1!, dict as CFDictionary, &error) else {
        throw error!.takeRetainedValue() as Error
    }

    print(shared1==shared2)


} else {
    // Fallback on earlier versions
    print("unsupported")
}

感谢@Mats 让我朝着正确的方向前进..3

【讨论】:

  • 有没有办法计算特定域参数('p'、'b'和'a')的公共和私有
  • 如何使用共享密钥数据加密和解密消息?函数SecKeyCreateEncryptedData 要求 SecKey 作为参数...但我得到数据
  • @Zohar Etzioni 我可以将 SecKeyCopyKeyExchangeResult 用于公共 JWK 密钥吗?如果是的话,有没有示例代码?
【解决方案2】:

这里是swift 5的最新代码和参数的变化。

var error: Unmanaged<CFError>?
  
       let keyPairAttr:[String : Any] = [kSecAttrKeySizeInBits as String: 256,
                                         SecKeyKeyExchangeParameter.requestedSize.rawValue as String: 32,
                                         kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
                                         kSecPrivateKeyAttrs as String: [kSecAttrIsPermanent as String: false],
                                         kSecPublicKeyAttrs as String:[kSecAttrIsPermanent as String: false]]
       let algorithm:SecKeyAlgorithm = SecKeyAlgorithm.ecdhKeyExchangeStandardX963SHA256//ecdhKeyExchangeStandardX963SHA256
       
       do {
           guard let privateKey = SecKeyCreateRandomKey(keyPairAttr as CFDictionary, &error) else {
               throw error!.takeRetainedValue() as Error
           }
           let publicKey = SecKeyCopyPublicKey(privateKey)
           print("public ky1: \(String(describing: publicKey)),\n private key: \(privateKey)")
           
        
           
           guard let privateKey2 = SecKeyCreateRandomKey(keyPairAttr as CFDictionary, &error) else {
               throw error!.takeRetainedValue() as Error
           }
           let publicKey2 = SecKeyCopyPublicKey(privateKey2)
           print("public ky2: \(String(describing: publicKey2)),\n private key2: \(privateKey2)")

           
           
           let shared:CFData? = SecKeyCopyKeyExchangeResult(privateKey, algorithm, publicKey2!, keyPairAttr as CFDictionary, &error)
           let sharedData:Data = shared! as Data
           print("shared Secret key: \(sharedData.hexEncodedString())")

           let shared2:CFData? = SecKeyCopyKeyExchangeResult(privateKey2, algorithm, publicKey!, keyPairAttr as CFDictionary, &error)
           let sharedData2:Data = shared2! as Data
           print("shared Secret key 2: \(sharedData2.hexEncodedString())")
           
           // shared secret key and shared secret key 2 should be same
       
       } catch let error as NSError {
           print("error: \(error)")
       } catch  {
           print("unknown error")
       }

【讨论】:

    【解决方案3】:

    大约 - 2020 年和 iOS13。在下面的 Zohar 代码 sn-p 中,还要在尝试获取共享密钥之前在字典中指定密钥大小。

    let dict: [String: Any] = [SecKeyKeyExchangeParameter.requestedSize.rawValue as String: 32]
    

    否则会出错。

    kSecKeyKeyExchangeParameterRequestedSize 不见了

    【讨论】:

      猜你喜欢
      • 2020-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-30
      • 2016-07-15
      • 1970-01-01
      相关资源
      最近更新 更多