我有项目,我需要使用私有数字签名(具有密码)签署字符串(raw或base64编码)。我在互联网上搜索,发现私人数字证书是x.509格式(RSA)。在xcode中,我将UIFileSharingEnabled设置为Enabled,并使用Itunes上传该rsa.p12证书。接下来,我从(数据或字符串)格式的文档目录中获取证书。我的问题是如何使用数字签名加密任何文本? 我试图使用这个lib https://github.com/TakeScoop/SwiftyRSA/issues,但是这个lib不支持x.509证书。
答案 0 :(得分:1)
我刚刚找到了编码字符串文本的代码,它可以正常工作
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
}
U还需要按名称获取文件
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