Swift creating secKey from privateKey

70 Views Asked by At

I'm new to this but I have a private key I got it from p12 cert using this command

openssl pkcs12 -in cert.p12 -nodes -out private.key.pem -nocerts

here's the content of the resulted file

Bag Attributes localKeyID: ======= friendlyName: ======= Key Attributes: -----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg1e12SFqNnD2aiLtB 2x5+K0R2pZDaBh2Drt09zLuL5imhRANCAASduIdkrmXpf5681JwnJHkcMi5zVPAS YFUig95A2w7flEY1lNtZcy/IRDQidqu/6BqLqe0V8P/CBZDa4hvKGzkE -----END PRIVATE KEY-----

and Then I tried to create a secKey from the content of this file, but I always get the same error

Unmanaged(_value: Error Domain=NSOSStatusErrorDomain Code=-50 "EC private key creation from data failed" UserInfo={numberOfErrorsDeep=0, NSDescription=EC private key creation from data failed})

here's the code

  func test() {
    let pemContent = """
     MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg1e12SFqNnD2aiLtB
     2x5+K0R2pZDaBh2Drt09zLuL5imhRANCAASduIdkrmXpf5681JwnJHkcMi5zVPAS
     YFUig95A2w7flEY1lNtZcy/IRDQidqu/6BqLqe0V8P/CBZDa4hvKGzkE
     """
    let pemData = pemContent
        .replacingOccurrences(of: "\n", with: "")
        .trimmingCharacters(in: .whitespacesAndNewlines)
    guard let decodedData = Data(base64Encoded: pemData) else {
        fatalError("Failed to decode Base64 data")
    }
    var attribute = [
        kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom,
        kSecAttrKeyClass: kSecAttrKeyClassPrivate,
        kSecAttrKeySizeInBits: 256
    ] as CFDictionary
    // Create the key
    var error: Unmanaged<CFError>?
    guard let secKey = SecKeyCreateWithData(decodedData as CFData,
                                            [
                                                kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom,
                                                kSecAttrKeyClass: kSecAttrKeyClassPrivate,
                                                kSecAttrKeySizeInBits: 256
                                            ] as CFDictionary,
                                            &error) else {
        if let createKeyError = error {
            print("Error creating key: \(createKeyError.takeRetainedValue() as Error)")
        }
        fatalError("Failed to create key")
    }
    
    // Successfully created SecKey
    print("SecKey created: \(secKey)")
}

Note: same key is working fine when I tried it in Android platform, but not in iOS

1

There are 1 best solutions below

0
TapulaRasa On

I was able to find a way to do this, I will post it here for anyone having the same issue, with the help of this question

  func privateKeyFromCertificate() -> SecKey {
      let certName : String = "yourCertName"
      let resourcePath: String = Bundle.main.path(forResource: certName, ofType: "p12")!
      let p12Data: NSData = NSData(contentsOfFile: resourcePath)!
      let key : NSString = kSecImportExportPassphrase as NSString
      let options : NSDictionary = [key : "CertificatePassword"]
      var privateKeyRef: SecKey? = nil
      var items : CFArray?
      let securityError: OSStatus = SecPKCS12Import(p12Data, options, &items)
      //let description : CFString = CFCopyDescription(items)
      //print(description)
      let theArray : CFArray = items!
      if securityError == noErr && CFArrayGetCount(theArray) > 0 {
          let newArray = theArray as [AnyObject] as NSArray
          let dictionary = newArray.object(at: 0)
          if let secIdentity = (dictionary as AnyObject).value(forKey: kSecImportItemIdentity as String) {
                      let securityError = SecIdentityCopyPrivateKey(secIdentity as! SecIdentity , &privateKeyRef)
                      if securityError != noErr {
                          privateKeyRef = nil
                      }
                  }
          
      }
    
    var error:Unmanaged<CFError>?
    if let cfdata = SecKeyCopyExternalRepresentation(privateKeyRef!, &error) {
       let data:Data = cfdata as Data
       let b64Key = data.base64EncodedString()
    }
      return privateKeyRef!
  }