首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >斯威夫特。验证文件签名问题。64字节而不是71字节

斯威夫特。验证文件签名问题。64字节而不是71字节
EN

Stack Overflow用户
提问于 2021-05-19 16:22:14
回答 2查看 177关注 0票数 1

我有一个任务是验证元数据的签名符合性,但由于某种原因,我使用的所有方法都返回'false‘。使用C#对文档进行签名的方式如下:

代码语言:javascript
复制
//Cert format X509Certificate2
var ecdsa = cert.GetECDsaPrivateKey());
byte[] signature;
signature = ecdsa.SignData(bufferedFileStream, HashAlgorithmName.SHA512);

我们得到了大小为64字节的签名

但swift原生方法生成size = 71字节的签名:

代码语言:javascript
复制
let signature = SecKeyCreateSignature(privateKey,
                                      .ecdsaSignatureMessageX962SHA256,
                                      fileData as CFData,
                                      &signError)

使用ECDSA NIST p256签名生成的证书算法- ecdsa-with-SHA256

到目前为止,我尝试了三种检查方法:

代码语言:javascript
复制
//1
SecKeyVerifySignature(publicKey,
                      .ecdsaSignatureMessageX962SHA256,
                      fileData as CFData,
                      signature as! CFData,
                      &error)
//2
SecKeyRawVerify(publicKey,
                .PKCS1SHA512,
                hashedDataBytes,
                digestLength,
                signatureBytes,
                signatureData.count)
//3
let publicKeyP265 = try! P256.Signing.PublicKey(x963Representation: bytesArray)
let ecdsaSignature = try! P256.Signing.ECDSASignature(rawRepresentation: signature)             
let result = publicKeyP265.isValidSignature(ecdsaSignature, for: fileData)

每种方法的结果都是否定的

到目前为止,我还没能成功验证签名,也许有人也遇到过类似的问题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-05-26 17:55:34

我用下一个代码解决了我的问题:

代码语言:javascript
复制
    let publicKeyP265 = try! P256.Signing.PublicKey(x963Representation: bytesArray)
    let ecdsaSignature = try! P256.Signing.ECDSASignature(rawRepresentation: signature)
    let fileDataDigest = SHA512.hash(data: fileData)
    
    let result = publicKeyP265.isValidSignature(ecdsaSignature, for: fileDataDigest)

我希望它能对其他人有用。

票数 -1
EN

Stack Overflow用户

发布于 2021-05-20 19:11:40

使用ECDSA和P256时,签名的大小与摘要的大小不同。ECDSA签名通常编码为DER格式。您将有DER字节的开销以及额外的符号字节(无论整数是有符号的还是无符号的)。

下面我使用python和密码库编写了一个简单的示例。您可以看到,签名的输出大小几乎总是70或更大。我还打印了DER签名的十六进制表示。

这里散列的大小很可能是无关紧要的。签名的最大区别在于EC密钥的密钥大小。

代码语言:javascript
复制
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec

message = b'Hello World'

for i in range(0, 10):
    sig = ec.generate_private_key(ec.SECP256R1()).sign(message, ec.ECDSA(hashes.SHA512()))
    print(f'{i}: {len(sig)} {sig.hex()}')

# 0: 71 30450221008466be7ca99fd80bc37527c078c30d07b725dd79feeb29816723259d27ccc367022051f1df8edbf82f528d587ce4db49e99b67cc6e8e61d83d90bfa050195c940721
# 1: 72 3046022100f478984dc0bccfb789713ab2ebb1636115ddaf55c7e8e44ba0c3b076e286def8022100a7ece3201a6cf521838a497510aede841bdc5ab2c59d225c2675a52b221419f6
# 2: 71 3045022100c6e8cfc1872f7aaa4d5c348bee5956ec7dc91422c07f382c402ac6d4265339f802206464c4e7d5d17b0bf28ba9b73cd16d4f1d59aa51d30144431a9367d3eb4fad78
# 3: 71 304502206ee73053a0479de84d1f5786705d121d9342bf1cc6d189fdfd30d55600e72b12022100efb16d5f5a4c7c1d60346e4c22395c955fa2abb2eb30f6649b1ee2c6921ac65a
# 4: 71 304502203a4f2ccec95a94b8b564a5abc837e39b33d338ad4c5ae421316644caac905722022100f78091452346154de97efdf7635c0c6bf74129e4868cd1c870f9b6ccbd20deac
# 5: 71 3045022100d960be8e6196de3e20098438783dfd8347163e5e78c631c592f1198ce3ffe1ef0220537a8e6efcbdcea3f15949c2896c88bd1b164474d34a367a33459e1db31b93d1
# 6: 72 3046022100a08a9e9cedec4341958b6690114a8e5569059e6c0bff3687acc3f49b53f3e105022100857932764645c8a195f4dd18820f12560be2ba2785fc745d49204aace2ebcfd8
# 7: 71 304502210087af13607c190d1656b0fc5d31b303f2616a92a7f516d5f528e8da59a61c0105022009094047f82158a6aca1b17ce6b276dc7122b7ecfebda7c517b6ab8770e40955
# 8: 71 3045022100885d72c1b31058f024d73d2a096cc662d847caf9db59b8483dd963fb70e6c3950220147ee83c980e2d866228c152e5c711817d3e60e60b7abff867ab9bd15b658777
# 9: 70 304402203eeb8b566a3198888bada3d346ab0caf7e14a882d1521120bee679209af2e4200220636100e9a6cd10386a9830a6c2885ee1fdfe00958473adb4bab1a85a0e3c8b11

因此,为了回答您的问题,请使用DER格式设置签名:

代码语言:javascript
复制
var ecdsa = cert.GetECDsaPrivateKey();
byte[] signature;
signature = ecdsa.SignData(bufferedFileStream, HashAlgorithmName.SHA512, DSASignatureFormat.Rfc3279DerSequence);

您可以找到函数here和支持的格式here的文档。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67599472

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档