'Create secKey form data/hex/bytes using SecKeyCreateWithData give nil
I'm new to encryption. i want to create public seckey from data but i always get nil. Please help me. I need this public key as seckey to create a shared secrete key but i always get nil . how i can convert data to seckey?
Below are the code for refrence. I'm using swift language.
 let attributes: [String:Any] = [
        kSecAttrKeyClass as String: kSecAttrKeyClassPublic,
        kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
        kSecAttrKeySizeInBits as String: 512,
        ]
var pubKey = publicKey2
var error1: Unmanaged<CFError>?
/// Create seckey
guard let pubSecKey = SecKeyCreateWithData((Data(bytes: publicKey2) as CFData), attributes as CFDictionary, &error1)else{
    print(error1?.takeRetainedValue().localizedDescription)
    return []
}
var error: Unmanaged<CFError>?
/// create shared key
guard let shared1 = SecKeyCopyKeyExchangeResult(LSILock.privtKey, .ecdhKeyExchangeCofactorX963SHA256, pubSecKey, keyPair, &error) else {
    return []
}
print(shared1)
Update
below are the bytes which i want to convert into seckey:
[12, 178, 30, 213, 113, 166, 59, 63, 203, 236, 182, 205, 126, 28, 81, 13, 94, 98, 67, 231, 152, 244, 180, 213, 168, 190, 237, 88, 131, 159, 173, 131, 75, 203, 51, 193, 115, 60, 36, 158, 27, 27, 174, 4, 211, 63, 25, 13, 174, 174, 64, 35, 59, 58, 151, 193, 167, 225, 13, 142, 237, 255, 25, 38]
if characteristic.uuid.uuidString == LSILock.AUTHENTICATION_KEY_EXHANGE {
                print(value)
                let hexValue = value.toHexString()
                print(hexValue)
                if let d = hexValue.lowercased().dataFromHexadecimalString() {
                    print(d.bytes)
                    LSILock.goForPrivatekeys = LSILock.goForPrivatekeys + 1
                    let dropFirst = d.bytes.dropFirst(1)
                    let dropLast = dropFirst.dropLast(3)
                        LSILock.lockPublicKey.append(contentsOf: dropLast)
                        if LSILock.goForPrivatekeys == 4{
                            LSILock.goForPrivatekeys = 0
                            let secKey = aesCTRencrytion(publicKey2: LSILock.lockPublicKey, keyPair: LSILock.keyPairs as CFDictionary)
                            print(secKey)
                            privateKeyExchange(secKey)
                        }
                }
            }
func dataFromHexadecimalString() -> Data? {
    let trimmedString = self.trimmingCharacters(in: CharacterSet(charactersIn: "<> ")).replacingOccurrences(of: " ", with: "")
    // make sure the cleaned up string consists solely of hex digits, and that we have even number of them
    let regex: NSRegularExpression?
    do {
        regex = try NSRegularExpression(pattern: "^[0-9a-f]*$", options: .caseInsensitive)
    } catch _ as NSError {
        regex = nil
    }
    let found = regex?.firstMatch(in: trimmedString, options: [], range: NSMakeRange(0, trimmedString.count))
    if found == nil || found?.range.location == NSNotFound || trimmedString.count % 2 != 0 {
        return nil
    }
    // everything ok, so now let's build NSData
    let data = NSMutableData(capacity: trimmedString.count / 2)
    for i in stride(from:0,to:trimmedString.count,by:2) {
        let start = trimmedString.index(trimmedString.startIndex, offsetBy: i)
        let end = trimmedString.index(trimmedString.startIndex, offsetBy: i+1)
        // get a sub-string with a ClosedRange
        let range = start...end
        let byteString = trimmedString[range]
        let num=UInt8(byteString.withCString { strtoul($0, nil, 16) })
        data?.append([num] as [UInt8], length: 1)
    }
    return data as Data?
}
func aesCTRencrytion( publicKey2 : [UInt8], keyPair : CFDictionary ) -> [UInt8]{
let message = "001C971A3456"
    let messageData   = message.dataFromHexadecimalString()!.bytes
print(ivData)
let attributes: [String:Any] = [
    kSecAttrKeyClass as String: kSecAttrKeyClassPublic,
    kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
    kSecAttrKeySizeInBits as String: 512,
    kSecReturnPersistentRef as String : true
    ]
var pubKey = publicKey2
var error1: Unmanaged<CFError>?
/// Create seckey
guard let pubSecKey = SecKeyCreateWithData((Data(bytes: publicKey2) as CFData), attributes as CFDictionary, &error1)else{
    print(error1?.takeRetainedValue().localizedDescription)
    return []
}
var error: Unmanaged<CFError>?
/// create shared key
guard let shared1 = SecKeyCopyKeyExchangeResult(LSILock.privtKey, .ecdhKeyExchangeCofactorX963SHA256, pubSecKey, keyPair, &error) else {
    return []
}
print(shared1)
}
Below i generate pair of keys:
func ecdhEncryption() {
        //        let privComponents = try? CC.EC.getPrivateKeyComponents(LSILock.keys!.0)
        //        let pubComponents = try? CC.EC.getPublicKeyComponents(LSILock.keys!.1)
        //
        //        let pubKey = try? CC.EC.createFromData( pubComponents!.keySize, pubComponents!.x, pubComponents!.y)
        //        print(pubKey)
        //                let pubKey1 = try? CC.EC.getPublicKeyFromPrivateKey(LSILock.keys!.0)
        //        print(pubKey1)
        //        guard let lock = LockSmartAPI.sharedInstance.getLock(lock_sn) else{return}
        //        lock.keyExchange(pubKey!)
        var publicKey = [UInt8]()
        var privateKey = [UInt8]()
        var publicKeySec, privateKeySec: SecKey?
        let keyattribute = [
            SecKeyKeyExchangeParameter.requestedSize.rawValue as String: 32,
            kSecAttrKeyType as String: kSecAttrKeyTypeEC,
            kSecAttrKeySizeInBits as String : 256
            ] as CFDictionary
        SecKeyGeneratePair(keyattribute, &publicKeySec, &privateKeySec)
        LSILock.keyPairs = keyattribute as! [String : Any]
        var error:Unmanaged<CFError>?
        if let publicCfdata = SecKeyCopyExternalRepresentation(publicKeySec!, &error) {
            let data:Data = publicCfdata as Data
            print(data)
            let b64Key = data.base64EncodedString()
            print(b64Key)
        }
        if let privateCfdata = SecKeyCopyExternalRepresentation(privateKeySec!, &error) {
            let data:Data = privateCfdata as Data
            print(data)
            let b64Key = data.base64EncodedString()
            print(b64Key)
        }
//        guard let privateKey1 = SecKeyCreateRandomKey(keyattribute as CFDictionary, &error) else {
//            return
//        }
//        let publicKey1 = SecKeyCopyPublicKey(privateKey1)
//        print(publicKey1 as? Data ?? Data())
        //                print(publicKeySec)
        //                print(privateKeySec)
        var error1: Unmanaged<CFError>?
        let keyData = SecKeyCopyExternalRepresentation(privateKeySec!, &error1)
        let data = keyData! as Data
        var privateKeyBytes = data.bytes
        privateKeyBytes.removeFirst()
        //For public key bytes will be divide into 2
        let pointSize = privateKeyBytes.count / 3
        let xBytes = privateKeyBytes[0..<pointSize]
        publicKey.append(contentsOf: xBytes)
        let yBytes = privateKeyBytes[pointSize..<pointSize*2]
        publicKey.append(contentsOf: yBytes)
        print(publicKey)
        //dBytes wont be there in public key
        let dBytes = privateKeyBytes[pointSize*2..<pointSize*3]
        privateKey.append(contentsOf: dBytes)
        // this x, y and d bytes can be expressed in HexaDecimal format or base64 format
        print(dBytes)
//        LSILock.privatekeys = Array(privateKey[0..<min(16,privateKey.count)])
        LSILock.privtKey = privateKeySec
        guard let lock = LockSmartAPI.sharedInstance.getLock(lock_sn) else{return}
        lock.keyExchange(publicKey)
    }
							
						Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source | 
|---|
