我需要在 iOS 应用程序中与 Hyperledger Fabric 进行交互,并且在创建提案签名时遇到了问题。 Fabric 需要低 S ECDSA,但我找不到在 Apple 的加密函数中指定它的方法。如果不指定 low-s,当 S 高于 R 时,我的调用大约有 50% 的时间会失败。
我的签名代码非常简单:
static func sign(data:Data, withPrivateKey:SecKey) throws -> Data {
var error: Unmanaged<CFError>?
guard
let signature = SecKeyCreateSignature(
withPrivateKey,
.ecdsaSignatureMessageX962SHA256,
data as CFData,
&error
) as Data?
else {
throw error!.takeRetainedValue()
}
return signature
}
根据 Hyperledger Fabric 代码中的注释,ECDSA 签名的“low-S”形式是 BIP-146 中描述的形式,即
s < n/2
,其中 n
是您的顺序曲线。刚刚 < r is not enough.
您可以自己将签名转换为“低 S”形式:将签名解析为
(r, s)
,根据需要翻转它 (s' = min(s, -s % n)
),并将结果 (r, s')
编码回字节。 X9.62 点编码不难解析,并且由于签名是公开的,因此您不必担心通过侧通道泄露秘密。