从iOS导出椭圆曲线密钥以使用OpenSSL
我在安全Enclave中生成并存储了一对私钥/公钥 它是256位椭圆曲线密钥。(唯一可以存储在Secure Enclave中的密钥类型) 我使用从iOS导出椭圆曲线密钥以使用OpenSSL,ios,swift,security,Ios,Swift,Security,我在安全Enclave中生成并存储了一对私钥/公钥 它是256位椭圆曲线密钥。(唯一可以存储在Secure Enclave中的密钥类型) 我使用SecKeyCreateWithData和SecKeyCopyExternalRepresentation在iOS设备之间导入/导出公钥,它可以正常工作 但是,导出的密钥似乎不适用于OpenSSL。 因为它总是在这个命令上显示“无法加载密钥” openssl ec -pubin -in public_key_file -text 导出密钥的方法是什么
SecKeyCreateWithData
和SecKeyCopyExternalRepresentation
在iOS设备之间导入/导出公钥,它可以正常工作
但是,导出的密钥似乎不适用于OpenSSL。
因为它总是在这个命令上显示“无法加载密钥”
openssl ec -pubin -in public_key_file -text
导出密钥的方法是什么?因此,我可以将其与OpenSSL一起使用。要使用OpenSSL,您需要
主题公钥信息(SPKI)
,或者DER
或者PEM
格式
SPKI包含基本信息,例如,key.type
,key.parameters
,key.value
SecKeyCopyExternalRepresentation
仅返回原始密钥二进制,该二进制仅为key.value
部分
您必须从该键.value
创建SPKI。通常的方法是读取ASN.1结构并将其编码为二进制编码的DER格式
但这里有一条捷径 Secure Enclave仅支持一种密钥类型,即256位EC密钥
secp256r1
(相当于OpenSSL中的prime256v1
)
DER格式的SPKI是二进制编码数据,例如
3059301306072a8648ce3d020106082a8648ce3d03010703420004fad2e70b0f70f0bf80d7f7cbe8dd4237ca9e59357647e7a7cb90d71a71f6b57869069bcdd24272932c6bdd51895fe2180ea0748c737adecc1cefa3a02022164d
它总是由两部分组成
305930106072a8648ce3d020106082a8648ce3d030107034200
04……
spki=fixed\u schema\u header+SecKeyCopyExternalRepresentation(…)
如果我在iOS中使用OpenSSL生成的密钥,我是否需要执行与此相反的过程?(这看起来像是从OpenSSL生成的密钥中删除了前52个字符)是的,SecKeyCreateWithData不需要固定的模式头,因此需要执行相反的操作。例如:CFDataDeleteBytes(可变数据、CFRangeMake(CFIndex(0)、headerSize))
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