Creating 32 bytes of data from public ec key x and y values

Hi All


I am trying to convert json jwk pulbic ec key to data format and i written below code which does that. But the data returned is 65 bytes in keyData variable below, instead of 32 bytes. Currently I am trying to pass this data of 32 bytes to GMEllipticCurveCrypto ( GMEllipticCurveSecp256r1 ) library which helps me create a shared secret but only takes in 32 bytes and if I pass this 65 bytes of data then I see a crash with error message as : Terminating app due to uncaught exception 'Invalid Key' ( reference : https://stackoverflow.com/questions/62063112/ios-creating-shared-secret-from-gmellipticcurvecrypto-using-a-public-jwk-ec-ke)


So can anyone please possibly help me generate a 32 bytes of data from public EC x and y values of public JWK key ?



var xStr = "XUvZlQ3ZYmB2kg-9fySt6Nk30ZnXAPWFa5tnIUGZuxs"
var yStr = "sHHTw0MHoiWw0lj7eOjgy95la1LOiMFpDqdolTZ1Trw"
//Padding required
xStr = xStr.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/")
if xStr.count % 4 == 2 {
xStr.append("==")
}
if xStr.count % 4 == 3 {
xStr.append("=")
}

yStr = yStr.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/")
if yStr.count % 4 == 2 {
yStr.append("==")
}
if yStr.count % 4 == 3 {
yStr.append("=")
}

let xBytes = Data(base64Encoded: xStr)
let yBytes = Data(base64Encoded: yStr)


//Now this bytes we have to append such that [0x04 , /* xBytes */, /* yBytes */, /* dBytes */]
//Initial byte for uncompressed y as Key.
let keyData = NSMutableData.init(bytes: [0x04], length: [0x04].count)
      keyData.append(xBytes!)
      keyData.append(yBytes!)
      //keyData.append(dBytes)
      let attributes: [String: Any] = [
          kSecAttrKeyType as String: kSecAttrKeyTypeEC,
          kSecAttrKeyClass as String: kSecAttrKeyClassPrivate,
          kSecAttrKeySizeInBits as String: 256,
          kSecAttrIsPermanent as String: false
      ]
      var error: Unmanaged?
      let keyReference = SecKeyCreateWithData(keyData as CFData, attributes as CFDictionary, &error)

print(keyData)

Replies

What you’re asking for doesn’t make sense. A SEC prime random 256 key consists of X and Y values that are always 32 bytes long. It’s simply impossible to create such a key from just 32 bytes.

I suspect that this 32 byte value you’re dealing with is the shared secret, but it’s hard to say with the code you’ve posted.

Also, is there a reason you’re involved a third-party library for this? It seems to carry its own EC implementation, which is probably unnecessary given that Apple platforms have had good EC APIs for a few years now (starting with iOS 10 and macOS 10.12).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Yes you are right i am trying to solve a problem related to generation of shared secret. I know apple has its own APIs for example using SecKeyCopyKeyExchangeResult to generate the shared secret. But when i tried that i was getting a error ( pad block corrupted on the server side ). So I thought of changing the generation of share secret using alternative methods to fix the pad block corrupted issue using hit and trial method.


The reason for looking 32 byte key data from x and y was that the below code and library generates 32 bytes of public key data to then generate shared secret. In the below if we try to po alicePair?.publicKey then we get 32 bytes of data.


//GMEllipticCurveCrypto

        let alicePair = GMEllipticCurveCrypto.generateKeyPair(for: GMEllipticCurveSecp256r1)
        let bobPair = GMEllipticCurveCrypto.generateKeyPair(for: GMEllipticCurveSecp256r1)
       
        let publicKeyAlice = alicePair?.publicKey
        let publicKeyBob = bobPair?.publicKey

        let shared1 = bobPair?.sharedSecret(forPublicKey: publicKeyAlice)
        let shared2 = alicePair?.sharedSecret(forPublicKey: publicKeyBob)

        if shared1 == shared2 {
            print("shared are same")
        } else {
            print("not matching")
        }


I guess then , we can close this issue. Can I raise a new question one with pad block issue corrupted and I can then put my actual implementiion of shared key using SecKeyCopyKeyExchangeResult ?

Created a new issue here for pad block corrupted: https://forums.developer.apple.com/message/422604#422604