利用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在不同语言的密钥格式不一样,所以过程中主 ...
随机推荐
- javascript refresh page 几种页面刷新的方法
Javascript刷新页面的几种方法:1 history.go(0) 2 location.reload() 3 location=location 4 location.a ...
- 使用 Visual Studio Team Test 进行单元测试和java中的测试
C#中test测试地 方法一. 1.从NUnit官网(http://www.nunit.org/index.php)下载最新版本NUnit,当前版本为NUnit2.5.8. 2.安装后,在VS2008 ...
- 基于WCF的API实现
本文程序基于VS2013.EF6.1.WCF WCF有2种方式,一是SOAP,一种是Restful 由于程序是基于PCL(可移植类库)的,所以不能用直接引入WCF服务的方式 网上的Restful方式的 ...
- 菜鸟学习Struts——配置Struts环境
刚开始学习Struts,它通过采用JavaServlet/JSP技术,实现了基于Java EEWeb应用的MVC设计模式的应用框架,是MVC经典设计模式中的一个经典产品. 要用到Struts就要学会配 ...
- swift UIAlertController教程
在iOS8中,UIAlertView与UIActionSheet都已经退休,取而代之的是UIAlertController!它的使用示范如下://弹出一个警告框,标题是“提示”,信息是“我的博客:oa ...
- Entity Framework(一) 映射
ADO.NET Entity Framework通过Modeel First和DataBase First,提供了几个把数据库表映射到对象上的曾.通过Database First,可以从一个数据库架构 ...
- 多路选择器(multiplexer)简介
1.多路器简介 简称:多路器 功能:多输入 单输出 组合逻辑电路 2.verilog代码实现: module Mux_8(addr,in1,in2,in3,in4,in5,in6,in7,in8 ...
- CS0016: 未能写入输出文件的解决方法
编译器错误消息: CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework\v2.0.50727 \Temporary ASP.NET Files\roo ...
- 团队项目之Sprint计划会议
一.我们团队在4月15日进行了冲刺计划会议,会议过程大致如下: 1.总结目前的工作进展,再一次确定所做项目的方向: 2.将之前的调查问卷的结果进行统计,做了需求分析,大致了解了用户的想法: 3.根据初 ...
- beego 0.9.0 中智能路由AutoRouter的使用方法及源码解读
了解beego的开发者肯定知道,beego的路由设计来源于sinatra,原来是不支持自动路由的,每一个路由都要自己配置的,如: type MainController struct { beego. ...