当前位置: 首页 > 知识库问答 >
问题:

Swift(Linux):提取CMS/PKCS#7证书并验证容器签名?

桂德义
2023-03-14
import Foundation
import OpenSSL

public final class BIOWrapper {

    public var bio = BIO_new(BIO_s_mem())

    public init(data: Data) {
        data.withUnsafeBytes { pointer -> Void in
            BIO_write(self.bio, pointer, Int32(data.count))
        }
    }

    public init() {}

    deinit {
        BIO_free(self.bio)
    }
}

public final class PKCS7Wrapper {

    public var pkcs7: UnsafeMutablePointer<PKCS7>

    public init(pkcs7: UnsafeMutablePointer<PKCS7>) {
        self.pkcs7 = pkcs7
    }

    deinit {
        PKCS7_free(self.pkcs7)
    }
}

我能够成功提取PKCS#7容器数据,并使用以下代码验证数据类型代码值是否为nid_pkcs7_signed:

let reqData = Data(bytes: reqBytes)
        guard reqData.count > 0 else {
            print("Empty request body")
            return nil
        }

        let bioWrapper = BIOWrapper(data: reqData)
        guard let container = d2i_PKCS7_bio(bioWrapper.bio, nil) else {
            print("No container")
            return nil
        }

        let pkcs7Wrapper = PKCS7Wrapper(pkcs7: container)
        let dataTypeCode = OBJ_obj2nid((pkcs7Wrapper.pkcs7.pointee.d.sign).pointee.contents.pointee.type)
        print("dataTypeCode : \(dataTypeCode)")

        if dataTypeCode == NID_pkcs7_data {
            print("GOT DATA!")
        } else {
            print("Didn't get data")
            return nil
        }

       let pkcs7SignedTypeCode = OBJ_obj2nid(pkcs7Wrapper.pkcs7.pointee.type)
        if let signed = pkcs7SignedTypeCode == NID_pkcs7_signed {
            print("Signed : \(signed)")
        }

然而,我现在已经到了一个我被卡住的地步。如何从PKCS#7有效载荷获取X.509证书数据?我可以看到pkcs7wrapper.pkcs7.pointee.d.sign.pointee.cert数据结构应该包含证书链数据。它的数据类型是unsafemutablePointer ,我想一旦我在内存中获得X.509证书数据,我就可以找到使用OpenSSL的pkcs7_verify方法的代码。我只是不知道怎么做那部分。

我找到了这个关于在OSX/IOS上验证收据的资源,它涉及到许多相同的问题。它们从文件系统获取X.509证书,并将数据传递到pkcs7_verify方法中。我只需要知道如何从PKCS#7容器中获取证书数据以传入。

有人能帮我做这个吗?我认识到从Swift调用C并不理想,但由于Swift没有一个好的安全/加密框架,我不知道有任何其他选择。

共有1个答案

呼延升
2023-03-14

答案的核心部分在您链接的代码中:

let store = X509_STORE_new()
X509_STORE_add_cert(store, appleRootX509)
OpenSSL_add_all_digests()
let result = PKCS7_verify(receiptPKCS7, nil, store, nil, nil, 0)
if result != 1 {
    log.atLevelDebug(id: 0, source: "Main", message: "Receipt signature verification failed")
    exit(errorCode)
}

您似乎忽略了这样一个事实,即不必亲自从PKCS7数据中提取X509证书。pkcs7_verify函数将作为验证的一部分执行以下操作:

尝试定位签名者的所有证书,首先查看certs参数(如果它不为空),然后查看p7结构本身中包含的任何证书。如果无法找到任何签名者的证书,则操作失败。

 类似资料:
  • 我试图实现PDFS的签名验证。这是一个很大的主题,所以我一步一步地进行,首先,我试图在我自己签名的PDF中实际返回一个正值,使用当前Acrobat的所有默认值--对于摘要,应该是SHA256和PKCS7分离签名。因此,我破解了openssl,通过读取PDF中给出的字节范围并调用函数,我得到了一个哈希值来进行比较。因此,现在我需要读取证书数据等,并使用函数。这个看起来就是我想要的: 如文档中所示。除

  • 问题内容: 在Java中需要有关加密例程的帮助。 给定PKCS#7签名,我想针对受信任的存储验证它包含的所有证书。我假设签名中包含的所有证书均以正确的顺序形成有效的证书路径(或链,无论如何),因此 最上面的(#0)是签名证书; 下一个(#1)是中间证书,用于签署#0; 下一个(#2)是另一个中间证书,用于签署#1; 等等。 最后一个证书(#N)由CA签名。 到目前为止,这是我设法破解的: 所以问题

  • 为了在OpenSSL中签名证书,我使用函数,向它提供一个请求(作为)、一个签名密钥和一个摘要。 现在我有我的签名密钥存储在HSM中,所以我无法提取它来签名证书。不幸的是,PKCS#11没有提供的等价物。它只有系列函数,这些函数对原始数据进行操作,而不是对证书进行操作。 有人能帮助我使用示例C/C++代码如何使用PKCS#11签署一个用OpenSSL创建的证书吗?

  • 也就是说,我需要创建一个可以通过WCF JSON调用公钥的客户机,以便稍后用于签名验证,但我似乎无法使其工作。首先,这里是我用来生成证书的代码: 完成后,我使用以下代码对消息进行签名: 最后,我试图验证:

  • 我检查了这个关于正确签名数据的问题,但它没有响应我的SCEP服务器的需求。我使用的代码来自EJBCA,但似乎没有向PKCS7签名数据添加证书。 当我使用工具解析签名数据时,我看到“证书”字段是“空的”。此外,当我尝试使用,我一无所获。 以下是我如何用Bouncy Castle签署我的数据(代码很多,但足以重现问题):