I need a help with creating P256.Signing.PublicKey from child key that were got with using HMAC-Sha256 hashing (we implemented key derivation). And after that get a SecKey
to create signature for messages
I can't understand how to decode it. Child keys in future will be used for keys exchange, signing and encrypting messages.
Keys example where taken from here :
private: eaa31c2e46ca2962227cf21d73a7ef0ce8b31c756897521eb6c7b39796633357
public: 02c9e16154474b3ed5b38218bb0463e008f89ee03e62d22fdcc8014beab25b48fa
So in future other device will send me such public key
02c9e16154474b3ed5b38218bb0463e008f89ee03e62d22fdcc8014beab25b48fa
And I should be able to decode it.
For now i'm able to decode private key in such way
extension String {
var hexData: Data? {
var data = Data(capacity: count / 2)
let regex = try! NSRegularExpression(pattern: "[0-9a-f]{1,2}", options: .caseInsensitive)
regex.enumerateMatches(in: self, range: NSRange(startIndex..., in: self)) { match, _, _ in
let byteString = (self as NSString).substring(with: match!.range)
let num = UInt8(byteString, radix: 16)!
data.append(num)
}
guard data.count > 0 else { return nil }
return data
}
}
It returns me a Data with 32 bytes length
let key = try P256.Signing.PrivateKey.init(rawRepresentation: hexData)
let attributes = [
kSecAttrKeyType: kSecAttrKeyTypeEC,
kSecAttrKeyClass: kSecAttrKeyClassPrivate,
kSecAttrKeySizeInBits: 256,
kSecAttrIsPermanent: false
] as [CFString: Any]
var error: Unmanaged<CFError>? = nil
let key = SecKeyCreateWithData(curveKeyData.x963Representation as CFData, attributes as CFDictionary, &error)
But it doesn't work for public key
Code for public key decoding.
// hexData - public key with length 33 bytes
do {
let key = try P256.Signing.PublicKey.init(rawRepresentation: hexData)
let attributes = [
kSecAttrKeyType: kSecAttrKeyTypeEC,
kSecAttrKeyClass: kSecAttrKeyClassPublic,
kSecAttrKeySizeInBits: 256,
kSecAttrIsPermanent: false
] as [CFString: Any]
let b = SecKeyCreateWithData(key.x963Representation as CFData, attributes as CFDictionary, nil)!
} catch {
print(error)
}
It fails with error incorrectParameterSize
Which says I'm doing some shit
The provided key material in the test vectors is in the compressed
form, which is not supported before iOS 16. As far as I know there's no way to create the key from compressed form before iOS 16, so you're left with one of the below mentioned methods. You should also adjust the way the key is exported on the other party.
iOS 13 and up
public init<D>(rawRepresentation: D) throws where D : ContiguousBytes
public init<Bytes>(compactRepresentation: Bytes) throws where Bytes : ContiguousBytes
public init<Bytes>(x963Representation: Bytes) throws where Bytes : ContiguousBytes
iOS 14 and up
public init(pemRepresentation: String) throws
public init<Bytes>(derRepresentation: Bytes) throws where Bytes : RandomAccessCollection, Bytes.Element == UInt8
If you can support iOS 16 you can use this function
public init<Bytes>(compressedRepresentation: Bytes) throws where Bytes : ContiguousBytes