Sha*_*man 7 c openssl digital-signature swift pkcs#7
我正在Swift 4中编写一组将在Linux上运行的服务.我需要做的一件事是接收使用加密消息语法(CMS)格式进行数字签名的有效负载,提取用于签名的证书,然后验证签名.我知道Linux上的Swift不包含用于此类事情的Security或CommonCrypto框架,所以我在OpenSSL中链接以尝试帮助解决这个问题.我距离我的C/C++编程时间已经有两年了,所以我很乐意承认我对这部分代码感到满意.
我有2个简单的类来充当OpenSSL BIO和PKCS7数据结构的包装器.它们看起来像这样:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
我能够成功提取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)")
}
Run Code Online (Sandbox Code Playgroud)
但是,我现在已经到了我被卡住的地步.如何从PKCS#7有效负载中获取X.509证书数据?我可以看到pkcs7Wrapper.pkcs7.pointee.d.sign.pointee.cert数据结构应该包含证书链数据.它的数据类型是UnsafeMutablePointer<stack_st_x509>,我认为PKCS7_verify一旦我在内存中获得X.509证书数据,我就可以找出使用OpenSSL 方法的代码.我只是不知道该怎么做.
我发现这个资源谈论验证OSX/iOS上的收据,这些收据涉及很多相同的问题.他们从文件系统获取X.509证书,并将数据传递给PKCS7_verify方法.我只需要知道如何从PKCS#7容器中获取证书数据.
谁能帮我这个?我认识到从Swift调用C并不理想,但是由于没有一个良好的Swift安全/加密框架,我不知道任何其他选项.
答案的核心部分在您链接的代码中:
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)
}
Run Code Online (Sandbox Code Playgroud)
您似乎缺少的是您不必自己从 PKCS7 数据中提取 X509 证书。该PKCS7_verify 函数将执行此操作作为验证的一部分:
尝试查找所有签名者的证书,首先查找 certs 参数(如果它不为 NULL),然后查找 p7 结构本身中包含的任何证书。如果无法找到任何签名者的证书,则操作将失败。
因此,您需要自己加载的唯一证书是根证书,您已经观察到它们从文件系统加载链接代码中的文件系统加载。
如果由于某种原因您仍然确实需要 Swift 解决方案从 PKCS7 数据中提取证书,则必须为 PKCS7 构建 ASN.1 解析器。不确定这是否适用于 Swift,这个简单的代码是快速搜索产生的,这是对 PKCS7 数据的很好的描述。
| 归档时间: |
|
| 查看次数: |
534 次 |
| 最近记录: |