利用BBRSACryptor实现iOS端的RSA加解密
背景
RSA这种非对称加密被广泛的运用于网络数据的传输,但其在iOS上很难直接实现,BBRSACryptor框架通过移植openssl实现了iOS端的RSA,本文将介绍如何使用BBRSACryptor生成证书,加载公钥,以及后端如何用php读取证书,加载私钥。
iOS加密
新建工程并集成BBRSACryptor
这个框架自带的demo将工程文件与框架放在了同一目录,因此在配置Header Search Paths时没有包含工程文件夹,一定注意,下面新建的工程将框架放在了工程文件夹内,因此头文件寻找路径需要包含上工程目录。详细步骤如下。
1. 新建一个iOS工程,将BBRSACryptor、GTMBase64、OpenSSL三个文件夹拖入工程,目录结构如下。
2.在Build Settings中配置Header Search Pathes。
注意最前面的文件夹名称要和自己的工程名相同
3.打开BBRSACryptor.m文件,修改存储证书的目录和文件路径,默认的是隐藏目录(前加点),为了方便查看与复制证书,建议将路径前面的点去掉,例如:
#define OpenSSLRSAKeyDir [DocumentsDir stringByAppendingPathComponent:@"openssl_rsa"]
#define OpenSSLRSAPublicKeyFile [OpenSSLRSAKeyDir stringByAppendingPathComponent:@"publicKey.pem"]
#define OpenSSLRSAPrivateKeyFile [OpenSSLRSAKeyDir stringByAppendingPathComponent:@"privateKey.pem"]
- 1
- 2
- 3
4.打开ViewController.m,导入BBRSACryptor.h和GTMBase64.h,使用下面的代码生成证书。
BBRSACryptor *rsaCryptor = [[BBRSACryptor alloc] init];
[rsaCryptor generateRSAKeyPairWithKeySize:1024];
- 1
- 2
运行后,在控制台会打印出证书路径,进入路径后,可以看到公钥和私钥证书。
5.使用TextEdit打开公钥证书,将—–BEGIN PUBLIC KEY—–和—–END PUBLIC KEY—–之间的部分复制,然后在工程中新建一个宏,来保存这个公钥,以便后续读取。
#define PublicKey \
@"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjYyZoASYgT+MIc/5YkSJngRbNYEQEI3UF7RVijF0STcMs93pH0qhjLJIQnsvUn2ghEVM4X+S+tQ0XhS+7tmL1UMEFgDgYwG/xr/ZjUozgQyvqeUejA08pbun0E0/Yx9WuBQfCpCc5vNka/ENDZEy/2PbEO5KD3hgsnH1JyNqNnwIDAQAB"
- 1
- 2
客户端仅保存公钥即可,私钥放在服务器上。使用php可以直接读取证书。
6.在客户端加载公钥与进行加密
前面已经创建了宏,以后通过宏即可加载公钥。如下:
BBRSACryptor *rsaCryptor = [[BBRSACryptor alloc] init];
// PublicKey是从公钥证书中复制的内容创建的宏,见上文。
[rsaCryptor importRSAPublicKeyBase64:PublicKey];
NSData *data = [rsaCryptor encryptWithPublicKeyUsingPadding:RSA_PADDING_TYPE_PKCS1 plainData:[@"客户端加密的内容" dataUsingEncoding:NSUTF8StringEncoding]];
NSString *baseStr = [GTMBase64 stringByEncodingData:data];
NSLog(@"%@",baseStr);
- 1
- 2
- 3
- 4
- 5
- 6
先加载公钥,然后把要加密的内容转换成NSData,加密后的内容先进行base64编码后再传输。为了验证能够解密,最后对base64编码的加密内容进行了打印,将这个内容先复制到剪贴板,后面贴在php中进行解密。
php解密
为了方便,将按照上文方法生成的私钥证书复制到服务器的某个目录,并在这个目录下创建一个php文件,并添加如下代码:
<?php
header("Content-type:text/html; charset=utf-8");
/**
* 密钥文件的路径
*/
$privateKeyFilePath = 'privateKey.pem';
/**
* 公钥文件的路径
*/
$publicKeyFilePath = 'publicKey.pem';
extension_loaded('openssl') or die('php需要openssl扩展支持');
(file_exists($privateKeyFilePath) && file_exists($publicKeyFilePath))
or die('密钥或者公钥的文件路径不正确');
/**
* 生成Resource类型的密钥,如果密钥文件内容被破坏,openssl_pkey_get_private函数返回false
*/
$privateKey = openssl_pkey_get_private(file_get_contents($privateKeyFilePath));
/**
* 生成Resource类型的公钥,如果公钥文件内容被破坏,openssl_pkey_get_public函数返回false
*/
$publicKey = openssl_pkey_get_public(file_get_contents($publicKeyFilePath));
($privateKey && $publicKey) or die('密钥或者公钥不可用');
// 这段内容来自上面iOS端打印的加密内容的base64编码
$encryptData = 'J0oTqBCNbsJauVwRz+380y519sSa7ficUO1NvRKiMGKUGJF0pomOu20fHqC77NmsKle9/L4DyYNr3xDgDa4SpO0in39rA9EYXzmx3rlyI1c8iPjAkQ6XpwZk7BsThiCFB/6QmkTW5pMIo4b0axRv/4lq1Rqx/YtuIsGkXQTNntI=';
$ee = base64_decode($encryptData);
$decryptData ='';
if (openssl_private_decrypt($ee, $decryptData, $privateKey)) {
echo '解密成功,解密后数据为:', $decryptData, PHP_EOL;
} else {
die('解密成功');
}
?>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
访问这个脚本,如果前面做的没有问题,会得到解密的结果:
php加密
使用私钥加密后,可以在客户端利用公钥解密。使用下面的代码进行加密。
<?php
header("Content-type:text/html; charset=utf-8");
/**
* 密钥文件的路径
*/
$privateKeyFilePath = 'privateKey.pem';
/**
* 公钥文件的路径
*/
$publicKeyFilePath = 'publicKey.pem';
extension_loaded('openssl') or die('php需要openssl扩展支持');
(file_exists($privateKeyFilePath) && file_exists($publicKeyFilePath))
or die('密钥或者公钥的文件路径不正确');
/**
* 生成Resource类型的密钥,如果密钥文件内容被破坏,openssl_pkey_get_private函数返回false
*/
$privateKey = openssl_pkey_get_private(file_get_contents($privateKeyFilePath));
/**
* 生成Resource类型的公钥,如果公钥文件内容被破坏,openssl_pkey_get_public函数返回false
*/
$publicKey = openssl_pkey_get_public(file_get_contents($publicKeyFilePath));
($privateKey && $publicKey) or die('密钥或者公钥不可用');
$originalData = '服务器加密的内容';
/**
* 加密以后的数据,用于在网路上传输
*/
$encryptData = '';
echo '原数据为:', $originalData, PHP_EOL;
///////////////////////////////用私钥加密////////////////////////
if (openssl_private_encrypt($originalData, $encryptData, $privateKey)) {
echo '加密成功,加密后数据(base64_encode后)为:', base64_encode($encryptData), PHP_EOL;
} else {
die('加密失败');
}
?>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
访问脚本后会打印出加密的base64编码,将这个编码复制到客户端进行解密,来验证可用性。
iOS解密
要在iOS端解密,和加密类似,先加载公钥,然后把base64编码的加密内容解码,解密后转为NSString即可。
BBRSACryptor *rsaCryptor = [[BBRSACryptor alloc] init];
[rsaCryptor importRSAPublicKeyBase64:PublicKey];
NSData *enCryptorDataBase64 = [@"aWdbPQHiQzU5CUOAIGQT3OD/MPqcqoXHXDFtYQPVRo9/Mb1S/aVcKQVHDjBpLgfzw+0mWxgHN6SuOfH8z9WobgQrTZh+pxhau3DnfukLmENGPWVMqquWMxTkEU7yCkx/RI7XEwv3jk9d4UgFOv35eqNUgYyWDq2gGatEpfnUg6U=" dataUsingEncoding:NSUTF8StringEncoding];
NSData *deCryptorData = [rsaCryptor decryptWithPublicKeyUsingPadding:RSA_PADDING_TYPE_PKCS1 cipherData:[GTMBase64 decodeData:enCryptorDataBase64]];
NSLog(@"%@",[[NSString alloc] initWithData:deCryptorData encoding:NSUTF8StringEncoding]);
- 1
- 2
- 3
- 4
- 5
不出意外的话,控制台将会打印出解密后的内容。
利用BBRSACryptor实现iOS端的RSA加解密的更多相关文章
- java与IOS之间的RSA加解密
很简单的一个需求,ipad端给密码RSA加密,传到java后台,解密.RSA加密算法是基于一个密钥对的,分为公钥和私钥,一般情况公钥加密,私钥解密,但也可私钥加密,公钥解密.还可以验签,就是先用私钥对 ...
- OpenSSL RSA加解密 (.Net公钥加密/ Linux端私钥解密)
要求在.Net端生成公钥私钥对. 然后在.Net端使用RSA公钥加密:在Linux端使用RSA私钥解密. 最初的尝试是:.Net端使用RSACryptoServiceProvider; linux端使 ...
- 全面解决.Net与Java互通时的RSA加解密问题,使用PEM格式的密钥文件
作者: zyl910 一.缘由 RSA是一种常用的非对称加密算法.所以有时需要在不用编程语言中分别使用RSA的加密.解密.例如用Java做后台服务端,用C#开发桌面的客户端软件时. 由于 .Net.J ...
- 前后端java+vue 实现rsa 加解密与摘要签名算法
RSA 加密.解密.签名.验签.摘要,前后端java+vue联调测试通过 直接上代码 // 注意:加密密文与签名都是唯一的,不会变化.// 注意:vue 端密钥都要带pem格式.java 不要带pem ...
- java RSA加解密以及用途
在公司当前版本的中间件通信框架中,为了防止非授权第三方和到期客户端的连接,我们通过AES和RSA两种方式的加解密策略进行认证.对于非对称RSA加解密,因为其性能耗费较大,一般仅用于认证连接,不会用于每 ...
- RSA算法原理——(3)RSA加解密过程及公式论证
上期(RSA简介及基础数论知识)为大家介绍了:互质.欧拉函数.欧拉定理.模反元素 这四个数论的知识点,而这四个知识点是理解RSA加密算法的基石,忘了的同学可以快速的回顾一遍. 一.目前常见加密算法简介 ...
- RSA加解密用途简介及java示例
在公司当前版本的中间件通信框架中,为了防止非授权第三方和到期客户端的连接,我们通过AES和RSA两种方式的加解密策略进行认证.对于非对称RSA加解密,因为其性能耗费较大,一般仅用于认证连接,不会用于每 ...
- RSA加解密&RSA加验签详解
RSA 加密算法是目前最有影响力的 公钥加密算法,并且被普遍认为是目前 最优秀的公钥方案 之一.RSA 是第一个能同时用于 加密 和 数字签名 的算法,它能够 抵抗 到目前为止已知的 所有密码攻击,已 ...
- Rsa加解密Java、C#、php通用代码 密钥转换工具
之前发了一篇"TripleDes的加解密Java.C#.php通用代码",后面又有项目用到了Rsa加解密,还是在不同系统之间进行交互,Rsa在不同语言的密钥格式不一样,所以过程中主 ...
随机推荐
- 版本控制器 (Svn,Git)
Svn: 集中式版本控制器,首先开发者在开始新一天的工作之前必须从服务器获取代码,然后进入自己的分支开发,开发完成后把自己的分支合并到主分支上进行提交,解决冲突.所有的版本信息都放在服务器上.如果脱离 ...
- php 获取数组第一个值的方法分享
以下是对使用php实现获取数组第一个值的方法进行了详细的分析介绍,需要的朋友可以过来参考下 reset (PHP 3, PHP 4, PHP 5)reset -- 将数组的内部指针指向第一个单元 说明 ...
- Crusher Django Tutorial(5) 使用内置管理员系统
http://crusher-milling.blogspot.com/2013/09/crusher-django-tutorial5-using-admin.html 顺便学习一下FQ Crush ...
- Git客户端TortoiseGit(Windows系统)的使用方法
本文环境: 操作系统:Windows XP SP3 Git客户端:TortoiseGit-1.8.8.0-32bit 一.安装Git客户端 全部安装均采用默认! 1. 安装支撑软件 msysgit: ...
- Windows7 sp1 64位下安装配置eclipse+jdk+CDT+minGW
需要的工具: jdk-7u11-windows-x64.exe eclipse-SDK-4.2.2-win32-x86_64.zip cdt-master-8.1.2.zip mingw-get-i ...
- OSM 中国数据(每天都在更新)
http://download.geofabrik.de/asia/china.html
- margin负值在页面布局中的应用
http://www.w3school.com.cn/tiy/t.asp 预览工具 一.左右列固定,中间列自适应布局 此例适用于左右栏宽度固定,中间栏宽度自适应的布局.由于网页的主体部分一般在中间,很 ...
- Notes of the scrum meeting(11/1)
meeting time:9:00~10:30p.m.,November 1st,2013 meeting place:20号公寓楼前 attendees: 顾育豪 ...
- 30款jQuery常用网页焦点图banner图片切换 下载
1.jquery 图片滚动特效制作 slide 图片类似窗帘式图片滚动 查看演示 2.jquery幻灯片插件带滚动条的圆形立体图片旋转滚动 查看演示 3.jQuery图片层叠旋转类似洗牌翻转图片幻灯片 ...
- IIS搭建本地服务器,花生壳实现外网通过域名访问网站
配置服务器 作为一个青年,没有实力,做不出标图所示的服务器. 作为一个学生,买不起服务器 作为一个小孩,买不起域名 但别忘了 作为一个平民玩家,只要有耐心 装备迟早会做出来的 (注:感觉有钱与没钱还是 ...