ios/swift中的椭圆曲线Diffie Hellman

vlf7wbxs  于 2022-12-15  发布在  iOS
关注(0)|答案(3)|浏览(172)

iOS是否会暴露用于生成密钥和使用ECDH派生密钥的API?
从我所看到的,苹果正在内部使用它(特别是x25519),但我没有看到它暴露为公共API的共同加密或其他。
谢谢你,
Z型

9njqaruj

9njqaruj1#

使用Xcode 8.3.3在playground中完成,使用EC为Alice、Bob生成私钥/公钥,然后使用Alice的私钥和Bob的公钥计算Alice的共享密钥,使用Bob的私钥和Alice的公钥计算Bob的共享密钥,最后Assert它们是相等的。

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给我指引了正确的方向......

gr8qqesn

gr8qqesn2#

下面是swift 5的最新代码和参数的变化。

import Security
import UIKit

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)\n\n")


    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)\n\n")


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

    let shared2:CFData? = SecKeyCopyKeyExchangeResult(privateKey2, algorithm, publicKey!, keyPairAttr as CFDictionary, &error)
    let sharedData2:Data = shared2! as Data
    print("shared Secret key 2: \(sharedData2.hexEncodedString())\n\n")

    // shared secret key and shared secret key 2 should be same

} catch let error as NSError {
    print("error: \(error)")
} catch  {
    print("unknown error")
}

extension Data {
    struct HexEncodingOptions: OptionSet {
        let rawValue: Int
        static let upperCase = HexEncodingOptions(rawValue: 1 << 0)
    }

    func hexEncodedString(options: HexEncodingOptions = []) -> String {
        let format = options.contains(.upperCase) ? "%02hhX" : "%02hhx"
        return self.map { String(format: format, $0) }.joined()
    }
}
scyqe7ek

scyqe7ek3#

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

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

字符串
否则这样说就错了。
缺少kSecKeyKeyExchangeParameterRequestedSize

相关问题