
<center>按下回车或点击查看完整尺寸图片</center>
进行加密和解密操作,需要公钥和私钥。这些密钥通常通过安全隔离区、随机字符串、密码生成,或者从证书中获取。
通过对数据进行签名,可以创建出一个数字签名。通过提供原始数据和签名,可以验证数据的完整性。
数字签名是接收方验证发送方身份真实性、数据完整性的保证。简单来说,它相当于手写签名。数字签名使用的是与加密/解密不同的另一套密钥对。
数字签名广泛应用于许多电子领域,例如当你要将应用提交测试或上传至App Store时,Xcode会对你的代码进行数字签名。通常,发送方对要发送的数据进行签名的流程如下:
接收方验证接收到的数据的流程如下:
在本教程中,用于数字签名的私钥将存储在安全隔离区中,而公钥则存储在安全隔离区之外,并与接收方共享。
class CryptoGraphicOperationViewModel {
var p12Data: Data
var password: String
init(fileName: String = "Certificate", ext: String = "p12", password: String = "1233") {
self.p12Data = Self.insertCertificate() ?? Data()
self.password = password
}
static func insertCertificate(fileName: String, ext: String, password: String) -> Data? {
return Utils.dataFromFile(name: fileName, withExtension: ext)
}
public func encrypt(data: Data, algorithm: SecKeyAlgorithm = .rsaEncryptionOAEPSHA512AESGCM) -> Data? {
guard let result = Utils.certificateDataFromP12(p12Data: self.p12Data, password: self.password) else { return nil }
guard let publicAndPrivateKey = Utils.publicAndPrivateKey(pkcs12Entry: result.pkcs12Entry) else { return nil }
return self.encrypt(value: data, publicKey: publicAndPrivateKey.publicKey, algorithm: algorithm)
}
public func decrypt(data: Data, algorithm: SecKeyAlgorithm = .rsaEncryptionOAEPSHA512AESGCM) -> Data? {
guard let result = Utils.certificateDataFromP12(p12Data: self.p12Data, password: self.password) else { return nil }
guard let publicAndPrivateKey = Utils.publicAndPrivateKey(pkcs12Entry: result.pkcs12Entry) else { return nil }
return self.decrypt(encrypted: data, privateKey: publicAndPrivateKey.privateKey, algorithm: algorithm)
}
public func sign(dataToSign: Data, algorithm: SecKeyAlgorithm = .rsaSignatureMessagePKCS1v15SHA512) -> Data? {
guard let result = Utils.certificateDataFromP12(p12Data: self.p12Data, password: self.password) else { return nil }
guard let publicAndPrivateKey = Utils.publicAndPrivateKey(pkcs12Entry: result.pkcs12Entry) else { return nil }
return self.signThe(data: dataToSign, privateKey: publicAndPrivateKey.privateKey, algorithm: algorithm)
}
public func verify(signedData: Data, signature: Data, algorithm: SecKeyAlgorithm = .rsaSignatureMessagePKCS1v15SHA512) -> Bool {
guard let result = Utils.certificateDataFromP12(p12Data: self.p12Data, password: self.password) else { return false }
guard let publicAndPrivateKey = Utils.publicAndPrivateKey(pkcs12Entry: result.pkcs12Entry) else { return false }
return self.verifySigned(data: signedData, signature: signature, publicKey: publicAndPrivateKey.publicKey, algorithm: algorithm)
}
internal func encrypt(value: Data, publicKey: SecKey, algorithm: SecKeyAlgorithm) -> Data? {
guard SecKeyIsAlgorithmSupported(publicKey, .encrypt, algorithm) else {
debugPrint("不支持的加密算法")
return nil
}
var errorRef: Unmanaged<CFError>?
guard let encryptedData = SecKeyCreateEncryptedData(publicKey, algorithm, value as CFData, &errorRef) else {
let error = errorRef?.takeRetainedValue()
debugPrint("加密错误:\(String(describing: error))")
return nil
}
return encryptedData as Data
}
internal func decrypt(encrypted: Data, privateKey: SecKey, algorithm: SecKeyAlgorithm) -> Data? {
guard SecKeyIsAlgorithmSupported(privateKey, .decrypt, algorithm) else {
debugPrint("不支持的解密算法")
return nil
}
var errorRef: Unmanaged<CFError>?
guard let decryptedData = SecKeyCreateDecryptedData(privateKey, algorithm, encrypted as CFData, &errorRef) as Data? else {
let error = errorRef?.takeRetainedValue()
debugPrint("解密错误:\(String(describing: error))")
return nil
}
return decryptedData
}
internal func signThe(data: Data, privateKey: SecKey, algorithm: SecKeyAlgorithm) -> Data? {
guard SecKeyIsAlgorithmSupported(privateKey, .sign, algorithm) else {
debugPrint("不支持的签名算法")
return nil
}
var errorRef: Unmanaged<CFError>?
guard let signature = SecKeyCreateSignature(privateKey, algorithm, data as CFData, &errorRef) as Data? else {
let error = errorRef?.takeRetainedValue()
debugPrint("签名错误:\(String(describing: error))")
return nil
}
return signature as Data
}
internal func verifySigned(data: Data, signature: Data, publicKey: SecKey, algorithm: SecKeyAlgorithm) -> Bool {
guard SecKeyIsAlgorithmSupported(publicKey, .verify, algorithm) else {
debugPrint("不支持的验证算法")
return false
}
guard data.isNotEmpty else {
debugPrint("无法使用空签名数据进行验证")
return false
}
var errorRef: Unmanaged<CFError>?
guard SecKeyVerifySignature(publicKey, algorithm, data as CFData, signature as CFData, &errorRef) else {
debugPrint("验证错误:\(String(describing: errorRef?.takeRetainedValue() as Error?))")
return false
}
return true
}
}// 创建访问控制对象
let access = SecAccessControlCreateWithFlags(
kCFAllocatorDefault, // 1
kSecAttrAccessibleWhenUnlockedThisDeviceOnly, // 2
[.privateKeyUsage, .biometryAny], // 3
nil // 4
)!
let secEnclaveTag = "YourKey".data(using: .utf8)! // 5
let privateKeyParams: [String: AnyObject] = [
kSecAttrIsPermanent as String: true as AnyObject, // 6
kSecAttrApplicationTag as String: secEnclaveTag as AnyObject, // 7
kSecAttrAccessControl as String: access // 8
]
let attributes = [
kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom, // 9
kSecAttrKeySizeInBits as String: 256, // 10
kSecAttrTokenID as String: kSecAttrTokenIDSecureEnclave, // 11
kSecPrivateKeyAttrs as String: privateKeyParams // 12
] as CFDictionary
var error: Unmanaged<CFError>?
guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
throw error!.takeRetainedValue() as Error
}
guard let publicKey = SecKeyCopyPublicKey(privateKey) else {
print("公钥生成错误")
return ""
}let message = "AshishAwasthi"
guard let messageData = message.data(using: String.Encoding.utf8) else {
print("无效的待签名消息。")
return nil
}
// 1. 创建签名
guard let signData = SecKeyCreateSignature(privateKey,
SecKeyAlgorithm.ecdsaSignatureMessageX962SHA256,
messageData as CFData,
nil) else {
print("签名错误")
return nil
}
// 2. 获取签名数据
let signedData = signData as Data
let signedString = signedData.base64EncodedString(options: [])
print("签名字符串", signedString)
// 3. 验证签名
let messageToVerify = "AshishAwasthi"
guard let messageDataToVerify = messageToVerify.data(using: String.Encoding.utf8) else {
print("ECC 无效的待验证消息")
return false
}
guard let signatureData = signedData else {
print("无效的待验证消息。")
return false
}
let verify = SecKeyVerifySignature(publicKey,
SecKeyAlgorithm.ecdsaSignatureMessageX962SHA256,
messageDataToVerify as CFData,
signatureData as CFData,
nil)在本教程中,您学到了:
如果您觉得本文信息量大,请考虑分享并留下反馈,以便它能触达更广泛的读者 👏👏👏👏👏 !!!!FINISHED
CSD0tFqvECLokhw9aBeRqun7QRQBiR11shbIyj7WeHfnF6U3xpa+0XjfU5DHXhvAyl5l+jExjFG4yiYEgxlUn78vQpdt/iTlM7OZ+q6Yb8t99Q5GsOMP/Y5LZ6+0EoZbl1FbJH3na1nVAFh5ucwQIyIF+TLXD5Sz9UGvbCO1uQo=
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。