'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