为了数据的安全传输,最近在搞证书的签名和验签需求,证书给的是pfx,由于这方便的资料太少,在这里记录一下。
使用的是Swift中的Security框架
读取pfx证书, 签名和验签都要使用
func readPfxFile(path: String, password: String) -> SecIdentity? {
var identity: SecIdentity?
let fileURL = URL(fileURLWithPath: path)
let data = try? Data(contentsOf: fileURL)
if let data = data {
let options: [CFString: Any] = [kSecImportExportPassphrase: password]
var importResult: CFArray?
let status = SecPKCS12Import(data as CFData, options as CFDictionary, &importResult)
if status == errSecSuccess, let items = importResult as? [AnyObject]{
let identityItem = items[0]
guard let cfIdentity = identityItem.value(forKey: kSecImportItemIdentity as String) as CFTypeRef?,
CFGetTypeID(cfIdentity) == SecIdentityGetTypeID() else {
return nil
}
identity = (cfIdentity as! SecIdentity)
}
}
return identity
}
提取私钥,签名
func signText(plainText: String, path: String, password: String) -> String? {
guard let identity = readPfxFile(path: path, password: password) else {
print("signText: SecIdentity is empty")
return nil
}
var aPrivateKey: SecKey?
let status = SecIdentityCopyPrivateKey(identity, &aPrivateKey)
if status != errSecSuccess {
print("signText: SecIdentityCopyPrivateKey error")
return nil
}
guard let privateKey = aPrivateKey else {
print("signText: privateKey is empty")
return nil
}
guard let plainData = plainText.data(using: .utf8) else {
print("signText: plainData is empty")
return nil
}
guard let resultData = SecKeyCreateSignature(privateKey, SecKeyAlgorithm.rsaSignatureMessagePKCS1v15SHA256, plainData as CFData, nil) else {
print("signText: resultData is empty")
return nil
}
let result = (resultData as Data).base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 0))
return result
}
提取公钥,验签
func verifySign(plainText: String, signature: String, path: String, password: String) {
guard let identity = readPfxFile(path: path, password: password) else {
print("verifySign: SecIdentity is empty")
return
}
var optCertificateRef : SecCertificate?
let secError = SecIdentityCopyCertificate(identity, &optCertificateRef)
guard secError == errSecSuccess, let certificate = optCertificateRef else {
print("verifySign: certificate is empty")
return
}
var aTrust: SecTrust?
let x509 = SecPolicyCreateBasicX509()
SecTrustCreateWithCertificates(certificate, x509, &aTrust)
guard let trust = aTrust else {
print("verifySign: trust is empty")
return
}
guard let publicKey = SecTrustCopyPublicKey(trust) else {
print("verifySign: publicKey is empty")
return
}
guard let plainData = plainText.data(using: .utf8) else {
print("verifySign: plainData is empty")
return
}
guard let signatureData = Data.init(base64Encoded: signature) else {
print("verifySign: signatureData is empty")
return
}
let result = SecKeyVerifySignature(publicKey, SecKeyAlgorithm.rsaSignatureMessagePKCS1v15SHA256, plainData as CFData, signatureData as CFData, nil)
print(result)
}