10

iOS 是否公开用于生成密钥的 API,以及使用 ECDH 导出密钥?

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

谢谢,

Z

4

3 回答 3

28

使用 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

于 2017-09-21T10:59:37.817 回答
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")
       }
于 2020-08-03T05:54:04.573 回答
1

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

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

或者这样说会出错。

kSecKeyKeyExchangeParameterRequestedSize不见了

于 2020-07-09T19:23:23.973 回答