从iOS导出椭圆曲线密钥以使用OpenSSL
我有一个私有/公钥对生成并存储在Secure Enclave中。从iOS导出椭圆曲线密钥以使用OpenSSL
它是256位椭圆曲线密钥。 (唯一可以存储在Secure Enclave中的密钥类型)。
我使用SecKeyCreateWithData
和SecKeyCopyExternalRepresentation
来导入/导出iOS设备之间的公钥,它工作。
但是,导出的密钥似乎不适用于OpenSSL。 因为它总是显示'unable to load Key'
这个命令。
openssl ec -pubin -in public_key_file -text
什么是导出密钥的方式吗?所以我可以在OpenSSL中使用它。
要使用OpenSSL,您需要subject public key info (SPKI)
,或者DER
或PEM
格式。
SPKI包含基本信息,例如,key.type
,key.parameters
,key.value
。
SecKeyCopyExternalRepresentation
只返回原始密钥二进制,它只是key.value
部分。您需要从key.value
创建SPKI。执行此操作的正常方法是读取https://tools.ietf.org/html/rfc5480,并将ASN.1结构编码为二进制编码的DER格式。
但是,这里有一条捷径。
Secure Enclave仅支持一种密钥类型,256位EC密钥secp256r1
(相当于OpenSSL中的prime256v1
)。
DER格式的SPKI是二进制编码的数据,例如,
3059301306072a8648ce3d020106082a8648ce3d03010703420004fad2e70b0f70f0bf80d7f7cbe8dd4237ca9e59357647e7a7cb90d71a71f6b57869069bcdd24272932c6bdd51895fe2180ea0748c737adecc1cefa3a02022164d
它总是由两个部分组成
固定模式头
3059301306072a8648ce3d020106082a8648ce3d030107034200
原始密钥值
04.......
您可以通过组合这两个部分来创建SPKI。
spki = fixed_schema_header + SecKeyCopyExternalRepresentation(...)
func createSubjectPublicKeyInfo(rawPublicKeyData: Data) -> Data {
let secp256r1Header = Data(bytes: [
0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00
])
return secp256r1Header + rawPublicKeyData
}
// Usage
let rawPublicKeyData = SecKeyCopyExternalRepresentation(...)!
let publicKeyDER = createSubjectPublicKeyInfo(rawPublicKeyData: rawPublicKeyData)
write(publicKeyDER, to: "public_key.der")
// Test with OpenSSL
// openssl ec -pubin -in public_key.der -text -inform der