带有数字签名的 Swift 签名字符串

标签 swift rsa signature sign digital

我有一个项目,我需要用私有(private)数字签名(有密码)对字符串(原始或 base64 编码)进行签名。我在互联网上搜索,发现私有(private)数字证书是 x.509 格式(RSA)。在 xcode 中,我将 UIFileSharingEnabled 设置为 Enabled 并使用 Itunes 上传了该 rsa.p12 证书。接下来,我以(数据或字符串)格式从文档目录中获取证书。我的问题是如何使用数字签名加密任何文本? 我尝试使用这个库 https://github.com/TakeScoop/SwiftyRSA/issues但是这个库不支持 x.509 证书。

最佳答案

我刚刚找到了编码字符串文本的代码并且它有效

 func signRequestorId(requestorID: String) -> String? {

    let name = "RSA256_4f1826090c554a439c419043270d40f7d.p12"
    guard let certificateData = CustomFileManager.getFile(by: name) else {
        return nil
    }

    var status: OSStatus

    let certificateKey = "123456"
    let options = [kSecImportExportPassphrase as String : certificateKey]

    var optItems: CFArray?
    status = SecPKCS12Import(certificateData as CFData, options as CFDictionary, &optItems)
    if status != errSecSuccess {
        print("Cannot sign the device id info: failed importing keystore.")
        return nil
    }
    guard let items = optItems else {
        return nil
    }

    // Cast CFArrayRef to Swift Array
    let itemsArray = items as [AnyObject]
    // Cast CFDictionaryRef as Swift Dictionary
    guard let myIdentityAndTrust = itemsArray.first as? [String : AnyObject] else {
        return nil
    }

    // Get our SecIdentityRef from the PKCS #12 blob
    let outIdentity = myIdentityAndTrust[kSecImportItemIdentity as String] as! SecIdentity
    var myReturnedCertificate: SecCertificate?
    status = SecIdentityCopyCertificate(outIdentity, &myReturnedCertificate)
    if status != errSecSuccess {
        print("Failed to retrieve the certificate associated with the requested identity.")
        return nil
    }

    // Get the private key associated with our identity
    var optPrivateKey: SecKey?
    status = SecIdentityCopyPrivateKey(outIdentity, &optPrivateKey)
    if status != errSecSuccess {
        print("Failed to extract the private key from the keystore.")
        return nil
    }
    // Unwrap privateKey from optional SecKeyRef
    guard let privateKey = optPrivateKey else {
        return nil
    }

    // Retrieve the digital signature and sign the requestor

    // Get the maximum size of the digital signature
    var signedBytesSize: size_t = SecKeyGetBlockSize(privateKey)
    var signedBytes: UnsafeMutablePointer<UInt8>

    // alloc a buffer to hold the signature
    signedBytes = UnsafeMutablePointer<UInt8>.allocate(capacity: signedBytesSize)
    memset(signedBytes, 0x0, signedBytesSize)
    // We're calling alloc here, so we need to destroy and deinit
    defer {
        signedBytes.deinitialize()
        signedBytes.deallocate(capacity: signedBytesSize)
    }

    // Sign data
    let requestorData = requestorID.data(using: String.Encoding.utf8)!
    // Generate a digital signature for our requestor from our cert
    let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: requestorData.count)
    let stream = OutputStream(toBuffer: buffer, capacity: requestorData.count)

    stream.open()
    requestorData.withUnsafeBytes({ (p: UnsafePointer<UInt8>) -> Void in
        stream.write(p, maxLength: requestorData.count)
    })

    stream.close()

    let weidformat = UnsafePointer<UInt8>(buffer)

    status = SecKeyRawSign(privateKey, .PKCS1, weidformat,
                           requestorData.count, signedBytes, &signedBytesSize)

    if status != errSecSuccess {
        print("Cannot sign the device id info: failed obtaining the signed bytes.")
        return nil
    }

    let encryptedBytes = NSData(bytes: signedBytes, length: signedBytesSize)
    let signedRequestorId = encryptedBytes.base64EncodedString(options: [])

    print(signedRequestorId)
    return signedRequestorId
}

你还需要函数按名称获取文档

static func getFile(by name: String)-> Data?{
    let documentsUrl =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
    let destinationUrl = documentsUrl!.appendingPathComponent("\(name)")

    let isFileFound = FileManager.default.fileExists(atPath: destinationUrl.path)
    if isFileFound {
        let documentContent = FileManager.default.contents(atPath: destinationUrl.path)
        return documentContent
    }
    return nil
}
enter code here

关于带有数字签名的 Swift 签名字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47718296/

相关文章:

请求 DocuSign API 签名时不发送电子邮件

python - 创建偏函数,但保留结果函数中的参数类型

ios - 在Swift中绘制椭圆中的彩虹渐变

ssl - 如何使用 'TLS1_ECDHE_RSA' 密码为 fips 平台生成带有 Openssl 的 pem 证书

c# - 我应该如何/应该使用 RSA 加密可变大小的数据 (RSACryptoServiceProvider)

java - .Net RSA加密,Java RSA解密

ios - 使用单元格大小自动布局调整表格 View 框架的大小以适应动态内容

SwiftUI View Builder 参数无法更改状态

swift - Swift 中的 Realm 迁移

html - 如何制作响应式签名邮件