4

I've been trying to encrypt a string with an elliptic curve encryption using Security swift library, and i'm getting an error on the line with SecKeyCreateEncryptedData(...) :

Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).

I guess the length and format of the data isn't conforming to the chosen algorithm, but i can't find any information about it in the documentation.

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, *) {
    guard let privateKey1 = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {return}

    let publicKey1 = SecKeyCopyPublicKey(privateKey1)
    guard let privateKey2 = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {return}

    let publicKey2 = SecKeyCopyPublicKey(privateKey2)

    let dict: [String: Any] = [:]

    guard let shared1 = SecKeyCopyKeyExchangeResult(privateKey1, SecKeyAlgorithm.ecdhKeyExchangeStandardX963SHA256, publicKey2!, dict as CFDictionary, &error) else {return}

    guard let shared2 = SecKeyCopyKeyExchangeResult(privateKey2, SecKeyAlgorithm.ecdhKeyExchangeStandardX963SHA256, publicKey1!, dict as CFDictionary, &error) else {return}

    print(shared1==shared2)

    let str = "Hello"
    let byteStr: [UInt8] = Array(str.utf8)
    let cfData = CFDataCreate(nil, byteStr, byteStr.count)

    guard let encrypted = SecKeyCreateEncryptedData(shared1 as! SecKey, SecKeyAlgorithm.eciesEncryptionStandardX963SHA256AESGCM, cfData!, &error) else {return}

    guard let decrypted = SecKeyCreateDecryptedData(shared2 as! SecKey, SecKeyAlgorithm.eciesEncryptionStandardX963SHA256AESGCM, encrypted, &error) else {return}


    print(decrypted)

} else {
    print("unsupported")
}
Arasuvel
  • 2,888
  • 1
  • 25
  • 39
Dany
  • 199
  • 1
  • 2
  • 12

1 Answers1

2

With the line

SecKeyCreateEncryptedData(shared1 as! SecKey, SecKeyAlgorithm.eciesEncryptionStandardX963SHA256AESGCM, cfData!, &error)

you are force casting shared1 to SecKey type. Force casting is (usually) a bad idea, an in your case it produces crash, because shared1 is not of SecKey type, but of CFData? type - because that is what SecKeyCopyKeyExchangeResult returns. From documentation:

func SecKeyCopyKeyExchangeResult(_ privateKey: SecKey, 
                           _ algorithm: SecKeyAlgorithm, 
                           _ publicKey: SecKey, 
                           _ parameters: CFDictionary, 
                           _ error: UnsafeMutablePointer<Unmanaged<CFError>?>?) -> CFData?

You can clearly see thet this function returns CFData?

mag_zbc
  • 5,941
  • 14
  • 36
  • 56
  • 1
    You're right. Thank you. But I've been trying to get the key for encrypting and decrypting data from that shared1/shared2 variable with this function: SecKeyCreateData(shared1, attributes as CFDictionary, &error). But in return i get a nil value. What should i do to get that key? – Dany Apr 25 '18 at 16:12
  • 1
    did you figure out how to use the sharedKey for encryption/decryption ? – Sparksmith Aug 22 '19 at 17:28
  • @Dany same for me... it's always nil...how did you solve? – Fabiosoft Apr 08 '20 at 11:12