iOS - 来自钥匙串的密钥与服务扩展

时间:2017-02-06 13:45:08

标签: ios keychain

我需要使用推送通知服务扩展共享主iOS应用生成的私钥。使用SecItemCopyMatching()获取密钥在应用程序中正常工作。但是,如果我尝试从服务扩展中获取私钥,我会得到一个“errSecItemNotFound”。

以下是我正在做的事情:

在主应用程序中,我生成一个密钥对,并使用SecItemAdd()将其存储在钥匙串中。生成密钥对时,我不使用“kSecAttrIsPermanent:true”属性,因为它不允许指定“kSecAttrAccessGroup”。据我所知,钥匙串共享我需要指定一个访问组,以便在应用之间或扩展和应用之间共享密钥。

kSecAttrAccessGroup是我指定的字符串,如下所示:“MyAppIdentifierPrefix”+“com.example.app.my-keychain” keyTag也是我指定的字符串,它看起来像这样:“com.example.app.my-key”

    // private key parameters
    let privateKeyParams: [String: AnyObject] = [
        kSecAttrApplicationTag as String: keyTag as AnyObject
    ]

    // public key parameters
    let publicKeyParams: [String: AnyObject] = [
        kSecAttrApplicationTag as String: keyTag as AnyObject
    ]

    // global parameters for key generation
    let parameters: [String: AnyObject] = [
        kSecAttrKeyType as String:          myKeyType,
        kSecAttrKeySizeInBits as String:    myKeySize as AnyObject,
        kSecPublicKeyAttrs as String:       publicKeyParams as AnyObject,
        kSecPrivateKeyAttrs as String:      privateKeyParams as AnyObject
    ]

    // generate the key pair
    var pubKey, privKey: SecKey?
    let status = SecKeyGeneratePair(parameters as CFDictionary, &pubKey, &privKey)

    if status == errSecSuccess {
        // parameters for public key
        let pubKeyParameters: [String: AnyObject] = [
            kSecClass as String: kSecClassKey,
            kSecAttrAccessible as String: kSecAttrAccessibleAlways,
            kSecAttrAccessGroup as String: keychainGroupName as AnyObject,
            kSecAttrIsPermanent as String: true as AnyObject,
            kSecAttrApplicationTag as String: keyTag as AnyObject,
            kSecAttrKeyType as String: myKeyType,
            kSecAttrKeySizeInBits as String: myKeySize as AnyObject,
            kSecAttrKeyClass as String: kSecAttrKeyClassPublic,
            kSecValueRef as String: pubKey!
        ]
        // add public key to keychain
        let statusPubKey = SecItemAdd(pubKeyParameters as CFDictionary, nil)

        // parameters for private key
        let privKeyParameters: [String: AnyObject] = [
            kSecClass as String: kSecClassKey,
            kSecAttrAccessible as String: kSecAttrAccessibleAlways,
            kSecAttrAccessGroup as String: keychainGroupName as AnyObject,
            kSecAttrIsPermanent as String: true as AnyObject,
            kSecAttrApplicationTag as String: keyTag as AnyObject,
            kSecAttrKeyType as String: myKeyType,
            kSecAttrKeySizeInBits as String: myKeySize as AnyObject,
            kSecAttrKeyClass as String: kSecAttrKeyClassPrivate,
            kSecValueRef as String: privKey!
        ]
        // add private key to keychain
        let statusPrivKey = SecItemAdd(privKeyParameters as CFDictionary, nil)
    }

我在功能标签中启用了钥匙串共享,并为应用和推送通知服务扩展指定了相同的标识符“com.example.app.my-keychain”

获取密钥字节的函数如下:

func getPrivateKeyData(keyTag: String) -> Data? {
    let parameters = [
        kSecClass as String: kSecClassKey,
        kSecAttrApplicationTag as String: keyTag,
        kSecAttrKeyClass as String: kSecAttrKeyClassPrivate,
        kSecAttrAccessGroup as String: keychainGroupName as AnyObject,
        kSecReturnData as String: true
        ] as [String : Any]
    var data: AnyObject?
    let status = SecItemCopyMatching(parameters as CFDictionary, &data)
    if status == errSecSuccess {
        return data as? Data
    } else { return nil }
}

到目前为止这不起作用......

0 个答案:

没有答案