我在iOS上生成了椭圆曲线私钥/公钥对,并将它们存储在安全区内的钥匙串中。
我想用这些密钥签名/验证邮件。
所以,这是我使用SecKeyCreateSignature
签署邮件的代码。
var error: Unmanaged<CFError>?
let signature = SecKeyCreateSignature(myPrivateKey,
.ecdsaSignatureMessageX962SHA512,
plainData as CFData,
&error)
效果很好,但SecKeyCreateSignature
仅适用于iOS 10.
我想至少保持与iOS 9的兼容性。所以我搜索了另一种签署消息的方式,我发现SecKeyRawSign
看起来与上面的函数类似。
但SecKeyRawSign
似乎不支持椭圆曲线键。
如何使用SecKeyRawSign
或其他方式签署/验证与上述代码等效或类似的消息?
答案 0 :(得分:1)
为了兼容性,您可以使用与SecKeyRawSign
类似的SecKeyCreateSignature
。
在这种情况下,它们不等同,因为创建签名的算法是不同的。但他们可以照常签字/核实。
func signCompat(privateKey: SecKey, rawData: Data) -> Data? {
if #available(iOS 10.0, *) {
return sign_iOS_10(privateKey: privateKey, rawData: rawData)
} else {
return sign_iOS_9(privateKey: privateKey, rawData: rawData)
}
}
@available(iOS 10.0, *)
func sign_iOS_10(privateKey: SecKey, rawData: Data) -> Data? {
let algorithm = SecKeyAlgorithm.ecdsaSignatureMessageX962SHA512
return SecKeyCreateSignature(privateKey, algorithm, rawData as CFData, nil) as Data?
}
func sign_iOS_9(privateKey: SecKey, rawData: Data) -> Data? {
let sha512digestedData = rawData.sha512()
var raw_signature_length = 512
let raw_signature_bytes = UnsafeMutablePointer<UInt8>.allocate(capacity: 512)
let osStatus = SecKeyRawSign(privateKey,
.PKCS1SHA512,
[UInt8](sha512digestedData),
Int(CC_SHA512_DIGEST_LENGTH),
raw_signature_bytes,
&raw_signature_length)
guard osStatus == errSecSuccess else { return nil }
return Data(bytes: raw_signature_bytes, count: raw_signature_length)
}
// The same logic is applied to verify
//
func verifyCompat(privateKey: SecKey, rawData: Data) -> Data? { ... }
@available(iOS 10.0, *)
func verify_iOS_10(privateKey: SecKey, rawData: Data) -> Data? { ... }
func verify_iOS_9(privateKey: SecKey, rawData: Data) -> Data? { ... }
您可以使用这些openssl命令检查是否正确。
// Sign
openssl dgst -sha512 -sign private.pem < test.pdf > signature.bin
// Verify
openssl dgst -sha512 -verify public.pem -signature signature.bin test.pdf