前言:

iOS常用的加密有很多种,前两天在工作中遇到了RSA加密,现在把代吗分享出来。

RSA基本原理

RSA使用"秘匙对"对数据进行加密解密.在加密解密数据前,需要先生成公钥(public key)和私钥(private key).

  • 公钥(public key): 用于加密数据. 用于公开, 一般存放在数据提供方, 例如iOS客户端.
  • 私钥(private key): 用于解密数据. 必须保密, 私钥泄露会造成安全问题

第一步:公钥、私钥的生成

iOS开发者可直接在Mac终端生成,命令如下,生成公钥der文件的时候需要填写国家地区等基本信息,也可直接忽略不填。生成私p12文件的时候需要填写密码,这个必填而且要记住,后面会用得着。

// 生成1024位私钥
openssl genrsa -out private_key.pem 1024
// 根据私钥生成CSR文件
openssl req -new -key private_key.pem -out rsaCertReq.csr
// 根据私钥和CSR文件生成crt文件
openssl x509 -req -days 3650 -in rsaCertReq.csr -signkey private_key.pem -out rsaCert.crt

// 为IOS端生成公钥der文件
openssl x509 -outform der -in rsaCert.crt -out public_key.der

// 将私钥导出为这p12文件
openssl pkcs12 -export -out private_key.p12 -inkey private_key.pem -in rsaCert.crt

第二步:加密相关的代码

在加密加密的时候需要定义公有变量公钥和私钥

  1. SecKeyRef _publicKey;
  2. SecKeyRef _privateKey;

加密相关的代码

  1. #pragma mark - 加密相关
  2. //用本地证书加载公钥
  3. - (void)loadPublicKeyWithPath:(NSString *)derFilePath
  4. {
  5. NSData *derData = [[NSData alloc] initWithContentsOfFile:derFilePath];
  6. if (derData.length > )
  7. {
  8. [self loadPublicKeyWithData:derData];
  9. }
  10. else
  11. {
  12. NSLog(@"load public key fail with path: %@", derFilePath);
  13. }
  14. }
  15. //加载公钥方法
  16. - (void)loadPublicKeyWithData:(NSData *)derData
  17. {
  18. SecCertificateRef myCertificate = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)derData);
  19. SecPolicyRef myPolicy = SecPolicyCreateBasicX509();
  20. SecTrustRef myTrust;
  21. OSStatus status = SecTrustCreateWithCertificates(myCertificate,myPolicy,&myTrust);
  22. SecTrustResultType trustResult;
  23. if (status == noErr) {
  24. status = SecTrustEvaluate(myTrust, &trustResult);
  25. }
  26.  
  27. SecKeyRef securityKey = SecTrustCopyPublicKey(myTrust); CFRelease(myCertificate); CFRelease(myPolicy); CFRelease(myTrust);
  28.  
  29. _publicKey = securityKey;
  30. }
  31.  
  32. //将文本内容加密
  33. - (NSString *)rsaEncryptText:(NSString *)text
  34. {
  35. NSData *encryptedData = [self rsaEncryptData:[text dataUsingEncoding:NSUTF8StringEncoding]];
  36. NSString *base64EncryptedString = [encryptedData base64EncodedStringWithOptions:];
  37. return base64EncryptedString;
  38. }
  39.  
  40. //分段再加密数据
  41. - (NSData *)rsaEncryptData:(NSData *)data
  42. {
  43. SecKeyRef key = _publicKey;
  44.  
  45. size_t cipherBufferSize = SecKeyGetBlockSize(key);
  46. uint8_t *cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));
  47. size_t blockSize = cipherBufferSize - ;
  48. size_t blockCount = (size_t)ceil([data length] / (double)blockSize);
  49. NSMutableData *encryptedData = [[NSMutableData alloc] init] ;
  50. for (int i = ; i < blockCount; i++)
  51. {
  52. size_t bufferSize = MIN(blockSize,[data length] - i * blockSize);
  53. NSData *buffer = [data subdataWithRange:NSMakeRange(i * blockSize, bufferSize)];
  54. OSStatus status = SecKeyEncrypt(key, kSecPaddingPKCS1,(const uint8_t *)[buffer bytes],[buffer length],cipherBuffer,&cipherBufferSize);
  55. if (status == noErr)
  56. {
  57. NSData *encryptedBytes = [[NSData alloc] initWithBytes:(const void *)cipherBuffer length: cipherBufferSize];
  58. [encryptedData appendData:encryptedBytes];
  59. }
  60. else
  61. {
  62. if (cipherBuffer) {
  63. free(cipherBuffer);
  64. } return nil;
  65. }
  66.  
  67. }
  68. if (cipherBuffer)
  69. {
  70. free(cipherBuffer);
  71.  
  72. }
  73. return encryptedData;
  74. }

第三步:解密相关代码

  1. #pragma mark - 解密相关
  2. - (void)loadPrivateKeyWithPath:(NSString *)p12FilePath password:(NSString *)p12Password
  3. {
  4. NSData *data = [NSData dataWithContentsOfFile:p12FilePath];
  5. if (data.length > )
  6. {
  7. [self loadPrivateKeyWithData:data password:p12Password];
  8. }
  9. else
  10. { NSLog(@"load private key fail with path: %@", p12FilePath);
  11. }
  12. }
  13. //生成私钥
  14. - (void)loadPrivateKeyWithData:(NSData *)p12Data password:(NSString *)p12Password
  15. {
  16. SecKeyRef privateKeyRef = NULL;
  17. NSMutableDictionary * options = [[NSMutableDictionary alloc] init];
  18.  
  19. [options setObject:p12Password forKey:(__bridge id)kSecImportExportPassphrase]; CFArrayRef items = CFArrayCreate(NULL, , , NULL);
  20. OSStatus securityError = SecPKCS12Import((__bridge CFDataRef)p12Data,
  21. (__bridge CFDictionaryRef)options,
  22. &items); if (securityError == noErr && CFArrayGetCount(items) > ) { CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, );
  23. SecIdentityRef identityApp = (SecIdentityRef)CFDictionaryGetValue(identityDict,
  24. kSecImportItemIdentity);
  25. securityError = SecIdentityCopyPrivateKey(identityApp, &privateKeyRef); if (securityError != noErr) {
  26. privateKeyRef = NULL;
  27. }
  28. }
  29.  
  30. _privateKey = privateKeyRef;
  31. CFRelease(items);
  32. }
  33.  
  34. //调用下面方法进行解密,最后返回一个字符串
  35. - (NSString *)rsaDecryptText:(NSString *)text
  36. {
  37. NSData *data = [[NSData alloc] initWithBase64EncodedString:text options:];
  38. NSData *decryptData = [self rsaDecryptData:data];
  39. NSString *result = [[NSString alloc] initWithData:decryptData encoding:NSUTF8StringEncoding];
  40. return result;
  41. }
  42.  
  43. //用私钥解密的方法,被上面方法调用
  44. - (NSData *)rsaDecryptData:(NSData *)data
  45. {
  46. SecKeyRef key = _privateKey;
  47.  
  48. size_t cipherLen = [data length];
  49. void *cipher = malloc(cipherLen);
  50.  
  51. [data getBytes:cipher length:cipherLen];
  52. size_t plainLen = SecKeyGetBlockSize(key) - ;
  53. void *plain = malloc(plainLen);
  54. OSStatus status = SecKeyDecrypt(key, kSecPaddingPKCS1, cipher, cipherLen, plain, &plainLen);
  55. if (status != noErr)
  56. {
  57. return nil;
  58. }
  59. NSData *decryptedData = [[NSData alloc] initWithBytes:(const void *)plain length:plainLen];
  60. return decryptedData;
  61. }

第四步:RSA加密解密的应用

在加密活解密之前一定要闲加载证书,然后再调用加密方法,直接上代码

  1. - (IBAction)decryptionBtnClick:(id)sender {
  2.  
  3. NSString *path = [[NSBundle mainBundle] pathForResource:@"public_key" ofType:@"der"];
  4. [self loadPublicKeyWithPath:path];
  5. path = [[NSBundle mainBundle] pathForResource:@"private_key" ofType:@"p12"];
  6. [self loadPrivateKeyWithPath:path password:@"bestnet"];
  7.  
  8. NSString *encryptStr = self.encryptTextFeild.text;
  9. if (encryptStr.length > )
  10. {
  11. NSString *miwen = [self rsaEncryptText:encryptStr];
  12. self.miWenLabel.text = [NSString stringWithFormat:@"加密结果:%@", miwen];
  13. if (miwen.length > )
  14. {
  15. self.decryptionTextFeild.text = [self rsaDecryptText:miwen];
  16. }
  17. }
  18. }

效果图

iOS常用加密之RSA加密解密的更多相关文章

  1. iOS动态部署之RSA加密传输Patch补丁

    概要:这一篇博客主要说明下iOS客户端动态部署方案中,patch(补丁)是如何比较安全的加载到客户端中. 在整个过程中,需要使用RSA来加密(你可以选择其它的非对称加密算法),MD5来做校验(同样,你 ...

  2. 【加密】RSA加密之实现

    private void btn_RSA_Click(object sender, EventArgs e) { //第一种方法调用 this.textBox1.Text = RSAEncrypt(& ...

  3. 【加密】RSA加密之算法

    RSA公钥加密算法是1977年由Ron Rivest.Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的. RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥, ...

  4. Java MD5加密与RSA加密

    区别: MD5加密: 加密时通过原字符串加密成另一串字符串 解密时需要原加密字符串进行重新加密比较两次加密结果是否一致 T=RSA加密: 加密时通过原字符串生成密钥对(公钥+私钥) 解密时通过公钥和私 ...

  5. MD5加密和RSA加密

    1.MD5加密  MD5(单向散列算法)的全称是Message-Digest Algorithm 5(信息-摘要算法),MD5算法的使用不需要支付任何版权费用. MD5的功能:     ①.输入任意长 ...

  6. iOS and JAVA 的 RSA 加密解密 (转载整理 )

    参考原文地址:http://www.cnblogs.com/makemelike/articles/3802518.html (至于RSA的基本原理,大家可以看 阮一峰的网络日志 的 RSA算法原理( ...

  7. android md5加密与rsa加解密实现代码

    import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security. ...

  8. iOS,一行代码进行RSA、DES 、AES、MD5加密、解密

    本文为投稿文章,作者:Flying_Einstein(简书) 加密的Demo,欢迎下载 JAVA端的加密解密,读者可以看我同事的这篇文章:http://www.jianshu.com/p/98569e ...

  9. RSA加密原理使用方式签名验证

      RSA加密原理使用方式签名验证 加密是网络传输中非常重要的一环,它保证了信息的安全性,让他人无法通过抓包来获取通讯的信息也无法通过伪造信息而实现对系统的入侵.其中最为常用的信息传递加密方式就是RS ...

随机推荐

  1. 剑指offer-4:变态条楼梯

    ##四.变态条楼梯 ###题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级.求该青蛙跳上一个n级的台阶总共有多少种跳法. ###分析 也是斐波那契数列问题,根据上述的思路,可 ...

  2. npm 命令行基本操作

    npm命令选项选项            说明search 在存储库中查找模块包 npm search expressinstall  使用在存储库或本地位置上的一个package.json文件来安装 ...

  3. (一)老毛桃U盘启动盘制作

    制作U盘启动盘前,一定要将U盘数据进行备份.U盘启动盘制作步骤: 1. 到老毛桃官网上下载U盘制作程序http://www.laomaotao.org.cn/. 2. 双击运行安装包,设置安装路径. ...

  4. 2019-11-29-git-需要知道的1000个问题

    title author date CreateTime categories git 需要知道的1000个问题 lindexi 2019-11-29 8:36:7 +0800 2018-2-13 1 ...

  5. 学习-Pytest(三)setup/teardown

    1. 用例运行级别 模块级(setup_module/teardown_module)开始于模块始末,全局的 函数级(setup_function/teardown_function)只对函数用例生效 ...

  6. 对mysql进行快照复制

    Myself> flush tables with read lock; 之后开始创建快照 [root@server0 mysql]# lvcreate -L 100M -s -n dbback ...

  7. Wannafly挑战赛22 C 多项式(大数,多项式极限)

    链接:https://ac.nowcoder.com/acm/contest/160/C 来源:牛客网 多项式 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言 ...

  8. STM32CubeIDE Debug Configurations

    新建完工程并编译后,配置Debug Configurations 此时双击STM32 MCU Debugging,如下图 此时就可以下载调试生成的LED.elf文件了

  9. 【新手】【十分钟上手系列-一】快速开发vue插件

    2018.6.28 在这浮躁的前端娱乐圈,不会三两个新框架都觉得自己不是前端.哦,不是我说的.说到底.原生才是重中之重.加油. vue用了大半年多,一直在用ui库,插件等,没有自己的东西. 想想连个v ...

  10. java打分系统

    package com.ioTest; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.Fil ...