ios - 如何使用带椭圆曲线 key 的 SecKeyRawSign 进行签名/验证

标签 ios swift security

我在 iOS 上生成了一个椭圆曲线私钥/公钥对,并将它们存储到安全飞地内的钥匙串(keychain)中。

我想用这些 key 签署/验证消息。

所以,这是我使用 SecKeyCreateSignature 签署消息的代码。

var error: Unmanaged<CFError>?
let signature = SecKeyCreateSignature(myPrivateKey,
                                      .ecdsaSignatureMessageX962SHA512,
                                      plainData as CFData,
                                      &error)

它运行良好,但 SecKeyCreateSignature 仅在 iOS 10 中可用。

我想至少保持与 iOS 9 的兼容性。所以我搜索了另一种签署消息的方法,我发现 SecKeyRawSign 看起来类似于上面的函数。

但是 SecKeyRawSign 看起来不支持椭圆曲线 key 。

如何使用 SecKeyRawSign 或其他方法来签署/验证与上述代码等效或相似的消息?

最佳答案

为了兼容性,您可以像使用 SecKeyCreateSignature 一样使用 SecKeyRawSign

在这种情况下,它们并不等价,因为创建签名的算法不同。但他们可以像往常一样签名/验证。


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

关于ios - 如何使用带椭圆曲线 key 的 SecKeyRawSign 进行签名/验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45055139/

相关文章:

ios - 除了 MVC,iOS 还使用了哪些设计模式?

ios - 在 tableView 中选择多个项目

ios - IBOutlet 初始化中的 UIView 框架中心不正确

language-agnostic - 揭开 Web 身份验证的神秘面纱

ios - 使用 AVCaptureMovieFileOutput 立即开始视频录制

ios - SceneKit 对象在它们的边界框而不是沿着网格发生碰撞

ios - swift 中具有重复实体值的核心数据

swift - 无法使用 Storyboard将窗口连接到 IBOutlet

ruby-on-rails - 如何测试 APNS p12 证书环境 ruby​​?

java - 在代码中存储数据库密码