Decrypt secp256r1

Hi, I try to decrypt some string. Does this code looks good? I get error: CryptoKit.CryptoKitError error 3.

do { guard let encryptedData = Data(base64Encoded: cardNumber), let securityKeyData = Data(base64Encoded: securityKey), let ivData = Data(base64Encoded: iv), let privateKeyData = Data(base64Encoded: privateKey) else { throw NSError(domain: "invalid_input", code: 1, userInfo: [NSLocalizedDescriptionKey: "Invalid Base64 input."]) }

    let privateKey = try P256.KeyAgreement.PrivateKey(derRepresentation: privateKeyData)
    let publicKey = try P256.KeyAgreement.PublicKey(derRepresentation: securityKeyData)
    let sharedSecret = try privateKey.sharedSecretFromKeyAgreement(with: publicKey)
    let symmetricKey = sharedSecret.hkdfDerivedSymmetricKey(
        using: SHA256.self,
        salt: Data(), 
        sharedInfo: Data(),
        outputByteCount: 32
    )

    let encryptedDataWithoutTag = encryptedData.dropLast(16)
    let tagData = encryptedData.suffix(16)
    let nonce = try AES.GCM.Nonce(data: ivData) 
    let sealedBox = try AES.GCM.SealedBox(nonce: nonce, ciphertext: encryptedDataWithoutTag, tag: tagData)
    let decryptedData = try AES.GCM.open(sealedBox, using: symmetricKey)
    resolve(decryptedCardNumber)

} catch {
    print("Decryption failed with error: \(error.localizedDescription)")
    reject("decryption_error", "Decryption failed with error: \(error.localizedDescription)", nil)
}
Answered by Maciejjj in 810375022

Found the solution:

this code:

    let symmetricKey = sharedSecret.hkdfDerivedSymmetricKey(
        using: SHA256.self,
        salt: Data(), 
        sharedInfo: Data(),
        outputByteCount: 32
    )

should be replaced with this code:

let symmetricKey = SymmetricKey(data: sharedSecret)
Does this code looks good?

Clearly not given, that it’s throwing an error (-:

It’s hard to answer questions like this without seeing a complete test vector. My general approach for debugging problems like this is to start by creating a round trip that’s entirely within CryptoKit. That is, use CryptoKit to encrypt some data and then use it to decrypt the same data. That should work, which gives you a starting point for further explanations.

Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Sorry, I now realize how unclear my comment was. Unfortunately, I don't have information on how the data is encrypted; I only have instructions on how to decrypt it. "The mobile application generates a pair of EC private/public keys using the SECP256R1 curve. Using the held private key and the public key received from the API, a shared key is derived and used to decrypt the received card number. The card number is encrypted using the AES algorithm in GCM mode." I have working encryption methods written in Java and Python, but I need one in Swift.

Can't edit :( I have working decryption methods*

A good first step is to decide whether this is a problem with:

  • Key agreement

  • Key derivation

  • GCM

If you run your Java or Python code and print the equivalent of sharedSecret and symmetricKey, do they match what you get in Swift?

Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Accepted Answer

Found the solution:

this code:

    let symmetricKey = sharedSecret.hkdfDerivedSymmetricKey(
        using: SHA256.self,
        salt: Data(), 
        sharedInfo: Data(),
        outputByteCount: 32
    )

should be replaced with this code:

let symmetricKey = SymmetricKey(data: sharedSecret)
Decrypt secp256r1
 
 
Q