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

作者: 以技术之名 | 来源:发表于2016-04-09 13:27 被阅读25177次

    更新:MD5加密是单向的,只能加密不能解密(破解除外)。标题可能会引起读者误解,已经改正,感谢Li_Cheng同学的提醒,另外笔者发现Li_Cheng同学有篇MD5加密更为详尽的文章,推荐阅读:iOS开发 关于MD5加密的相关使用

    加密的Demo,欢迎下载

    java端的加密解密,读者可以看我同事的这篇文章http://www.jianshu.com/p/98569e81cc0b

    最近做了一个移动项目,是有服务器和客户端类型的项目,客户端是要登录才行的,服务器也会返回数据,服务器是用Java开发的,客户端要同时支持多平台(Android、iOS),在处理iOS的数据加密的时候遇到了一些问题。起初采取的方案是DES加密,老大说DES加密是对称的,网络抓包加上反编译可能会被破解,故采取RSA方式加密。RSA加密时需要公钥和私钥,客户端保存公钥加密数据,服务器保存私钥解密数据。(iOS端公钥加密私钥解密、java端公钥加密私钥解密,java端私钥加密公钥解密都容易做到,iOS不能私钥加密公钥解密,只能用于验签)。

    问题

    问题1:iOS端公钥加密的数据用Java端私钥解密。

    iOS无论使用系统自带的sdk函数,用mac产生的或者使用java的jdk产生的公钥和私钥,进行加密解密自己都可以使用。不过ios加密,java解密,或者反过来就不能用了。要么是无法创建报告个-9809或-50的错误,要么解出来是乱码。ios系统函数种只有用公钥加密,私钥解密的方式。而公钥加密每次结果都不同。

    MAC上生成公钥、私钥的方法,及使用
    • 1.打开终端,切换到自己想输出的文件夹下
    • 2.输入指令:openssl(openssl是生成各种秘钥的工具,mac已经嵌入
    • 3.输入指令:genrsa -out rsa_private_key.pem 1024 (生成私钥,java端使用的)
    • 4.输入指令:rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout (生成公钥)
    • 5.输入指令:pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt(私钥转格式,在ios端使用私钥解密时用这个私钥)

      注意:在MAC上生成三个.pem格式的文件,一个公钥,两个私钥,都可以在终端通过指令vim xxx.pem 打开,里面是字符串,第三步生成的私钥是java端用来解密数据的,第五步转换格式的私钥iOS端可以用来调试公钥、私钥解密(因为私钥不留在客户端)

      详细步骤

    问题2:服务器返回数据也要加密,老大打算用java私钥加密,ios用公钥解密(由于iOS做不到用私钥加密公钥解密,只能私钥加密公钥验签),所以这种方案也有问题。

    通过看一些大牛的介绍,了解了iOS常用的加密方式
    • 1 通过简单的URLENCODE + BASE64编码防止数据明文传输
    • 2 对普通请求、返回数据,生成MD5校验(MD5中加入动态密钥),进行数据完整性(简单防篡改,安全性较低,优点:快速)校验
    • 3 对于重要数据,使用RSA进行数字签名,起到防篡改作
    • 4 对于比较敏感的数据,如用户信息(登陆、注册等),客户端发送使用RSA加密,服务器返回使用DES(AES)加密

      原因:客户端发送之所以使用RSA加密,是因为RSA解密需要知道服务器私钥,而服务器私钥一般盗取难度较大;如果使用DES的话,可以通过破解客户端获取密钥,安全性较低。而服务器返回之所以使用DES,是因为不管使用DES还是RSA,密钥(或私钥)都存储在客户端,都存在被破解的风险,因此,需要采用动态密钥,而RSA的密钥生成比较复杂,不太适合动态密钥,并且RSA速度相对较慢,所以选用DES)

      所以此次加密,我们选择了第四种加密方式

    加密方式

    ios端进行DES加密、解密时非常方便

    1、引入头文件 #import "DES3Util.h"
    2、加密时调用类方法  +(NSString *) encryptUseDES:(NSString *)plainText key:(NSString *)key;
    3、解密时调用类方法  +(NSString *)decryptUseDES:(NSString *)cipherText key:(NSString *)key;
    

    ios端进行RSA加密、解密时非常方便

    1、引入头文件 #import "RSAUtil.h"
    2、公钥加密时调用类方法:
    + (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey;
    + (NSData *)encryptData:(NSData *)data publicKey:(NSString *)pubKey;
    3、私钥解密时调用类方法 
    + (NSString *)decryptString:(NSString *)str privateKey:(NSString *)privKey;
    + (NSData *)decryptData:(NSData *)data privateKey:(NSString *)privKey;
    

    ios端进行MD5加密、解密时非常方便

    1、引入头文件 #import "MD5Util"
    2、加密时调用方法:- (NSString *)md5:(NSString *)str;
    

    ios端进行AES加密、解密时非常方便

    1、引入头文件 #import "AES.h"
    2、加密时调用方法
    + (NSString *)encrypt:(NSString *)message password:(NSString *)password;
    2、解密时调用的方法
    + (NSString *)decrypt:(NSString *)base64EncodedString password:(NSString *)password;
    

    有关RSA、MD5、AES加密的原理介绍

    效果图

    Encryption.gif

    相关文章

      网友评论

      • Hanfank:加上这篇文章终于打开理解了RSA算法https://www.lvtao.net/dev/android_ios_php_openssl.html
      • 863c73f31933:楼上,你了解sm4加解密不?
      • 一个不太努力的代码搬运工:楼主写的很棒,赞一个!
      • 069eea124da3:请问md5如何解密?
        以技术之名:@知音_0797 md5不可以解密哦,是单向的
      • codermali:你好,请教你一个问题.我最近碰到了这个问题,就是Java后台向我给一个公钥,然后我需要加密之后把数据传递给后台,但是后台却不能解密,这个应该怎么解决啊?
      • d9f4f5f6f173:非常感谢楼主,新人学到了很多干货。请再接再厉哈:+1:
      • CarrieQ:终于碰见大神了
      • 贱精先玍丶:作者,在define文件里要修改 公钥私钥那些宏定义吗? 还是直接按文章说的直接调用方法就行了? 新手搞不太懂,还望解答
      • 爱可乐爱可乐:其实rsa原理是公钥私钥可以互相加解密,我也研究了好久,终于找到了解法,rsa运算量很大,所以都是用来传递后面des密匙的。具体做法可以看我的github:https://github.com/0xfeedface1993/zxSockethttps://github.com/0xfeedface1993/zxSocketServer
      • 贱精先玍丶:楼主, 新手想问下, 只是请求参数加密怎么弄呢?登录的
      • 问问问你:ciphertext = [GTMBase64 stringByEncodingData:data];
        这一句是用base64来对nsdata进行编码吗?
      • jch497:每次调用了UIImagePickerController之后 -(SecKeyRef)addPrivateKey:(NSString *)key方法里的 SecItemAdd() 返回的status 报-34018的错 其他时候都不会报错 按照网上的说法开启KeyChain Sharing也没用 不知道有遇到过没
      • bf544aca9a15:Demo里面Rsa看不到效果,需要什么配置吗,在线等
      • 谁遇而安:RSA运行起来为啥加密之后什么都没有呀?
        凉风起君子意如何:xcode8以后,选中targets -> capabilities ->keychain sharing 将开关打开,重新运行就好了
      • 困惑困惑困惑:服务器通过MD5加密跟iOS通过MD5加密的数据不一样咋回事啊,大神
      • enoughpower:收藏了,这里纠正一点,MD5不是加密算法,MD5属于哈希算法的一种。
      • 28bb64fffadd:Reading from private effective user settings.点击 rsa生成密钥的时候直接打印这个是什么意思哦?我在 xcode8.1上运行的
      • d17e852c43be:额 楼主 我RSA加密返回空的呀 OSStatus status = SecItemAdd((__bridge CFDictionaryRef)publicKey, &persistKey); 这句代码后 返回-34018 :fearful:
        jch497:不知道你解决了没 我也会遇到这个-34018的报错 但是都是在我调用UIImagePickerController之后 其他时候都是正常的
      • 在没老之前:楼主,RAS+base64加密,啥意思啊?我先获取公钥,使用公钥对密码进行RSA加密,然后呢?
      • fd40d2db2097:写的好!学习了
      • Tate_code:刚好项目要用,写得很全面哈哈😄
      • coco_CC:你好,我下载下来打开好多文件变红了,可以看下怎么回事吗?刚接触加密解密,想通过你的文章和代码学习下,谢谢。
      • iChang:楼主,我按照你的步骤来生成密钥,然后解密结果为nil,换成你的密钥就好了,pem文件里的字符串要做什么处理吗?
        iChang:@Flying_Einstein
      • 99c604b78416:这文章标题上来就错了!MD5是一种是用于确保信息传输完整一致的散列算法,虽然经常跟密码(验证)相关,但跟加密真的没有一毛钱关系……
      • 流年易逝_李:您好,您的aes加密结果好像好像和您同事java端的结果不一样,可以帮忙看一下吗?qq:1365343119,谢谢
      • GaryHuang:BaseViewController.m怎么没有啊 都是红的
      • 35607579afd6:des加密后端做了PKCS7Padding支持?
      • Li_Cheng:md5有解密么
        以技术之名:@Li_Cheng 已经更改,谢谢提醒。
        Li_Cheng:@Flying_Einstein 看下文章,md5的标题,写错了
        以技术之名:@Li_Cheng md5是单项的,只能加密不能解密,当然,破解不算:joy:
      • Yanni_L:加密出来的是经过GTMBase64加密了吧, 我现在要16进制的, 怎么处理啊
      • fanaf:还是吊,每次加密,加密什么东东?
      • 横渡:你的代码在哪?
        以技术之名:@横渡 最上方,github链接~
      • 白鹿Divella:不知道楼主是否研究过pfx,cer类型的文件可以直接用来加密解密吗?必须生成p12和der文件的类型或者pem类型的吗?
      • Alcander:不错
      • 柴茝:不错哦~赞一个
      • 系统盘:有源码分享一下吗?
        以技术之名:@我旁边坐了一个胖子 我们公钥和私钥是提前生成好的,分别保留在了客户端和服务器
        系统盘:@Flying_Einstein 我在想,第一次以什么请求发送给服务器让它把公钥发回给我,然后我再对密码进行加密再发送然后再得到token,那比如登录的话不就是两次请求了吗
        以技术之名:@我旁边坐了一个胖子 文章最上方是github地址
      • 努力奔跑的H先生:最近要用到,感谢分享
      • 阳光的大男孩儿:一脸懵逼,二脸懵逼,三脸懵逼~~~
        阳光的大男孩儿: @devchen 我是大神,德莱文😏😏😏
        devchena:@依然那么爱你forever 我竟然在这里看见你了
        以技术之名:@依然那么爱你forever :joy::joy::joy::joy::joy::joy:
      • nebouxii:本来还想找个iOS实习工作 ,看到这里 一脸懵逼
        以技术之名:@彼尔德丘 很多东西都是工作中学的,我也有很多很多不懂得,慢慢学再提高
      • 1d9b104216d2:为什么不直接用https…:sweat:
        以技术之名:@我旁边坐了一个胖子 没注意是http还是https,但是京东首页一些产品信息都可以抓下来
        系统盘:@Flying_Einstein https收费的吧
        以技术之名:@姜禹 老大是网络安全硕士,对iOS也不太熟悉,我对网络安全这块也不是太了解~就按老大意思办了
      • ddaa8dae50b0:认证阶段使用非对称密码系统, 认证结束后动态生成只有客户端和服务端掌握的对称密码进行加密, 这样比较有效率. 全部用非对称的计算量想必很头疼.

        非对称密码界没有私钥加密的说法, 私钥只能用来生成签名和解密, 公钥只能验签和加密, 这是基本概念, 不是iOS不支持. 网络上太多人混淆了这个概念, 才会出现私钥加密的说法, 导致后来的人学习的时候很困惑.
        以技术之名:@Ian_He 看的我一脸懵逼,确实不懂,我只是实现了这个需求,更深层次的东西理解的不多,不过仍旧谢谢你,有空了研究一下数据安全的东西
        ddaa8dae50b0: @Flying_Einstein 加密经过哈希的用户密码, 服务端存用户密码的哈希值. 认证过程中, 客户端和服务器可以用diffie-hellman密钥交换协议协商密钥, 这个迷药第三方是无法在有效时间内破解.
        以技术之名:@Ian_He 又get到了好多新知识,有个问题,认证阶段用非对称的加密系统,加密的应该是什么信息呢?用户名和密码?认证结束后,使用动态生成的客户端和服务端掌握的对称密码,如果对称密码破解了,那么这次网络请求的信息不就被拿到了??
      • ALittleNasty:最近要用,非常感谢:pray:
        以技术之名:@ALittleNasty 分享交流,共同进步
      • 郭之源:整理好了,我要转载喽😁
        以技术之名:@郭之源 把你的加密Java代码写一篇附上:stuck_out_tongue_winking_eye::stuck_out_tongue_winking_eye::stuck_out_tongue_winking_eye:

      本文标题:iOS,一行代码进行RSA、DES 、AES加密、解密及MD5加

      本文链接:https://www.haomeiwen.com/subject/zifblttx.html