news 2026/5/12 13:18:18

使用iOS安全API进行数据加密、解密、签名与验证完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用iOS安全API进行数据加密、解密、签名与验证完整指南
按下回车或点击查看完整尺寸图片

1. 加密与解密的基础知识

进行加密和解密操作,需要公钥和私钥。这些密钥通常通过安全隔离区、随机字符串、密码生成,或者从证书中获取。

2. 什么是签名和验证?

通过对数据进行签名,可以创建出一个数字签名。通过提供原始数据和签名,可以验证数据的完整性。

数字签名是接收方验证发送方身份真实性、数据完整性的保证。简单来说,它相当于手写签名。数字签名使用的是与加密/解密不同的另一套密钥对。

数字签名广泛应用于许多电子领域,例如当你要将应用提交测试或上传至App Store时,Xcode会对你的代码进行数字签名。通常,发送方对要发送的数据进行签名的流程如下:

  • 发送方使用特定的哈希算法(例如:sha256)对数据进行加密。哈希算法的输出称为"摘要"(例如:6e04f289)。
  • 然后,发送方使用自己的私钥摘要进行加密。这个加密后的摘要就是数据的"数字签名"。
  • 发送方将原始数据加密后的摘要一起发送出去。请注意,加密后的摘要仅用于验证发送方身份,而消息本身并未使用签名和验证所用的同一私钥进行加密。消息的加密是通过类似于上一节所述方式创建的私钥来完成的。

接收方验证接收到的数据的流程如下:

  • 接收方收到消息及其数字签名。
  • 接收方使用发送方的公钥解密数字签名 -> 得到的结果是摘要
  • 接收方使用与发送方相同的哈希算法,对收到的明文数据进行哈希运算 -> 这将输出一个摘要
  • 如果步骤2(数字签名解密后)输出的摘要 = 步骤3(对接收到的明文数据哈希后)输出的摘要 -> 接收方就可以验证数据的完整性。

在本教程中,用于数字签名的私钥将存储在安全隔离区中,而公钥则存储在安全隔离区之外,并与接收方共享。

从证书中获取公钥和私钥

classCryptoGraphicOperationViewModel{varp12Data:Datavarpassword:Stringinit(fileName:String="Certificate",ext:String="p12",password:String="1233"){self.p12Data=Self.insertCertificate()??Data()self.password=password}staticfuncinsertCertificate(fileName:String,ext:String,password:String)->Data?{returnUtils.dataFromFile(name:fileName,withExtension:ext)}publicfuncencrypt(data:Data,algorithm:SecKeyAlgorithm=.rsaEncryptionOAEPSHA512AESGCM)->Data?{guardletresult=Utils.certificateDataFromP12(p12Data:self.p12Data,password:self.password)else{returnnil}guardletpublicAndPrivateKey=Utils.publicAndPrivateKey(pkcs12Entry:result.pkcs12Entry)else{returnnil}returnself.encrypt(value:data,publicKey:publicAndPrivateKey.publicKey,algorithm:algorithm)}publicfuncdecrypt(data:Data,algorithm:SecKeyAlgorithm=.rsaEncryptionOAEPSHA512AESGCM)->Data?{guardletresult=Utils.certificateDataFromP12(p12Data:self.p12Data,password:self.password)else{returnnil}guardletpublicAndPrivateKey=Utils.publicAndPrivateKey(pkcs12Entry:result.pkcs12Entry)else{returnnil}returnself.decrypt(encrypted:data,privateKey:publicAndPrivateKey.privateKey,algorithm:algorithm)}publicfuncsign(dataToSign:Data,algorithm:SecKeyAlgorithm=.rsaSignatureMessagePKCS1v15SHA512)->Data?{guardletresult=Utils.certificateDataFromP12(p12Data:self.p12Data,password:self.password)else{returnnil}guardletpublicAndPrivateKey=Utils.publicAndPrivateKey(pkcs12Entry:result.pkcs12Entry)else{returnnil}returnself.signThe(data:dataToSign,privateKey:publicAndPrivateKey.privateKey,algorithm:algorithm)}publicfuncverify(signedData:Data,signature:Data,algorithm:SecKeyAlgorithm=.rsaSignatureMessagePKCS1v15SHA512)->Bool{guardletresult=Utils.certificateDataFromP12(p12Data:self.p12Data,password:self.password)else{returnfalse}guardletpublicAndPrivateKey=Utils.publicAndPrivateKey(pkcs12Entry:result.pkcs12Entry)else{returnfalse}returnself.verifySigned(data:signedData,signature:signature,publicKey:publicAndPrivateKey.publicKey,algorithm:algorithm)}internalfuncencrypt(value:Data,publicKey:SecKey,algorithm:SecKeyAlgorithm)->Data?{guardSecKeyIsAlgorithmSupported(publicKey,.encrypt,algorithm)else{debugPrint("不支持的加密算法")returnnil}varerrorRef:Unmanaged<CFError>?guardletencryptedData=SecKeyCreateEncryptedData(publicKey,algorithm,valueasCFData,&errorRef)else{leterror=errorRef?.takeRetainedValue()debugPrint("加密错误:\(String(describing:error))")returnnil}returnencryptedDataasData}internalfuncdecrypt(encrypted:Data,privateKey:SecKey,algorithm:SecKeyAlgorithm)->Data?{guardSecKeyIsAlgorithmSupported(privateKey,.decrypt,algorithm)else{debugPrint("不支持的解密算法")returnnil}varerrorRef:Unmanaged<CFError>?guardletdecryptedData=SecKeyCreateDecryptedData(privateKey,algorithm,encryptedasCFData,&errorRef)asData?else{leterror=errorRef?.takeRetainedValue()debugPrint("解密错误:\(String(describing:error))")returnnil}returndecryptedData}internalfuncsignThe(data:Data,privateKey:SecKey,algorithm:SecKeyAlgorithm)->Data?{guardSecKeyIsAlgorithmSupported(privateKey,.sign,algorithm)else{debugPrint("不支持的签名算法")returnnil}varerrorRef:Unmanaged<CFError>?guardletsignature=SecKeyCreateSignature(privateKey,algorithm,dataasCFData,&errorRef)asData?else{leterror=errorRef?.takeRetainedValue()debugPrint("签名错误:\(String(describing:error))")returnnil}returnsignatureasData}internalfuncverifySigned(data:Data,signature:Data,publicKey:SecKey,algorithm:SecKeyAlgorithm)->Bool{guardSecKeyIsAlgorithmSupported(publicKey,.verify,algorithm)else{debugPrint("不支持的验证算法")returnfalse}guarddata.isNotEmptyelse{debugPrint("无法使用空签名数据进行验证")returnfalse}varerrorRef:Unmanaged<CFError>?guardSecKeyVerifySignature(publicKey,algorithm,dataasCFData,signatureasCFData,&errorRef)else{debugPrint("验证错误:\(String(describing:errorRef?.takeRetainedValue()asError?))")returnfalse}returntrue}}

从iOS安全隔离区生成密钥

// 创建访问控制对象letaccess=SecAccessControlCreateWithFlags(kCFAllocatorDefault,// 1kSecAttrAccessibleWhenUnlockedThisDeviceOnly,// 2[.privateKeyUsage,.biometryAny],// 3nil// 4)!letsecEnclaveTag="YourKey".data(using:.utf8)!// 5letprivateKeyParams:[String:AnyObject]=[kSecAttrIsPermanentasString:trueasAnyObject,// 6kSecAttrApplicationTagasString:secEnclaveTagasAnyObject,// 7kSecAttrAccessControlasString:access// 8]letattributes=[kSecAttrKeyTypeasString:kSecAttrKeyTypeECSECPrimeRandom,// 9kSecAttrKeySizeInBitsasString:256,// 10kSecAttrTokenIDasString:kSecAttrTokenIDSecureEnclave,// 11kSecPrivateKeyAttrsasString:privateKeyParams// 12]asCFDictionaryvarerror:Unmanaged<CFError>?guardletprivateKey=SecKeyCreateRandomKey(attributesasCFDictionary,&error)else{throwerror!.takeRetainedValue()asError}guardletpublicKey=SecKeyCopyPublicKey(privateKey)else{print("公钥生成错误")return""}

创建签名

letmessage="AshishAwasthi"guardletmessageData=message.data(using:String.Encoding.utf8)else{print("无效的待签名消息。")returnnil}// 1. 创建签名guardletsignData=SecKeyCreateSignature(privateKey,SecKeyAlgorithm.ecdsaSignatureMessageX962SHA256,messageDataasCFData,nil)else{print("签名错误")returnnil}// 2. 获取签名数据letsignedData=signDataasDataletsignedString=signedData.base64EncodedString(options:[])print("签名字符串",signedString)// 3. 验证签名letmessageToVerify="AshishAwasthi"guardletmessageDataToVerify=messageToVerify.data(using:String.Encoding.utf8)else{print("ECC 无效的待验证消息")returnfalse}guardletsignatureData=signedDataelse{print("无效的待验证消息。")returnfalse}letverify=SecKeyVerifySignature(publicKey,SecKeyAlgorithm.ecdsaSignatureMessageX962SHA256,messageDataToVerifyasCFData,signatureDataasCFData,nil)

总结

在本教程中,您学到了:

  • 对称加密与非对称加密及解密的区别。
  • 如何在iOS应用中使用Swift安全API实现非对称加密。
  • iOS安全元件/隔离区。
  • 数字签名和验证。
  • 如何通过安全隔离区对数据进行数字签名和验证。

结语

如果您觉得本文信息量大,请考虑分享并留下反馈,以便它能触达更广泛的读者 👏👏👏👏👏 !!!FINISHED
CSD0tFqvECLokhw9aBeRqun7QRQBiR11shbIyj7WeHfnF6U3xpa+0XjfU5DHXhvAyl5l+jExjFG4yiYEgxlUn78vQpdt/iTlM7OZ+q6Yb8t99Q5GsOMP/Y5LZ6+0EoZbl1FbJH3na1nVAFh5ucwQIyIF+TLXD5Sz9UGvbCO1uQo=
更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)
对网络安全、黑客技术感兴趣的朋友可以关注我的安全公众号(网络安全技术点滴分享)

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 22:06:09

机器视觉中的九点平移标定

机器视觉中的九点平移标定 图像二维空间到机械手二维空间的转换 标定文件 <?xml version"1.0" encoding"UTF-8"?> <CalibInfo><CalibInputParam><CalibParam ParamName"CreateCalibTime" DataType"string">…

作者头像 李华
网站建设 2026/4/18 22:07:03

用ComfyUI生成无限时长AI数字人探索之路

最近几天&#xff0c;我沉浸在一项深度探索中。这一切源于我想用AI生成一个能“无限时长”说话的数字人。听起来很酷&#xff0c;对吧&#xff1f;但现实却给了我几个“下马威”。1. 理想与现实的碰撞&#xff1a;当“无限”遇到瓶颈起初&#xff0c;我使用了一个现成的工作流&…

作者头像 李华
网站建设 2026/4/18 22:06:11

岭回归(Ridge Regression)辨析

岭回归&#xff08;Ridge Regression&#xff09;完整辨析 岭回归是线性回归最经典、最稳健的正则化变体&#xff0c;几乎是2026年所有高维、共线性、特征工程不彻底场景下的“默认备选”模型。下面从原理 → 公式 → 与其他模型对比 → 使用场景 → 优缺点 → 常见误区&#…

作者头像 李华
网站建设 2026/4/18 22:13:21

Python基于flask框架广西桂林旅游服务网站系统-Pycharm django

目录技术选型与项目背景开发环境搭建系统架构设计核心模块实现数据交互与优化测试与安全扩展功能建议性能监控与维护开发技术路线结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;技术选型与项目背景 Flask框架轻量级优势与适用场景分…

作者头像 李华
网站建设 2026/4/18 22:06:15

Python基于flask框架的的小区运动场地中心预约管理系统的设计与实现-vue-Pycharm django

目录技术选型与框架介绍系统功能模块设计数据库设计核心API接口实现前后端交互实现权限控制与安全部署与测试扩展优化方向开发技术路线结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;技术选型与框架介绍 后端采用Python Flask框架&a…

作者头像 李华