利用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在不同语言的密钥格式不一样,所以过程中主 ...
随机推荐
- Python脚本控制的WebDriver 常用操作 <二十七> 文件下载
测试用例场景 webdriver允许我们设置默认的文件下载路径.也就是说文件会自动下载并且存在设置的那个目录中. Python脚本 测试用Python代码: # coding=gbk ''' Crea ...
- ActiveMQ之MessageListener
消息的消费者接收消息可以采用两种方式: 1.consumer.receive()或 consumer.receive(int timeout); 2.注册一个MessageListener. 采用第一 ...
- 关于WP8 微信分享的补充说明
1.根据微信官方Demo完成相应功能. 2.在分享完后,从微信回来,需要进行 快速恢复. 3.在快速恢复中加入 RootFrame.Navigating += HandlerFotResetNavig ...
- Java的别名机制
基本类型存储了实际的数值,而并非指向一个对象的引用,所以在为其赋值的时候,是直接将一个地方的内容复制到另一个地方. 但是在为对象"赋值"的时候,情况却发生了变化.对一个对象进行操作 ...
- 使用OPTIMIZE TABLE命令来整理表碎片实践
操作环境:ubuntu 14.10 mysql 5.6.25 对含有BLOB或TEXT字段的表,若经常做修改或删除类的操作,需要定期执行OPTIMIZE TABLE命令来整理碎片. 1.creat ...
- js之正则表达式(上)
1.正则表达式的创建方式 两种方式创建:通过new修饰符创建和字面量的方式创建 1>new修饰符方式创建 var b2=new RegExp('Box','ig'); //第二个参数是 模式字符 ...
- python学习小结5:封装、继承、多态
面向对象程序设计中的类有三大特性: 继承,封装,多态 继承:以普通的类为基础建立专门的类对象 封装:对外部世界隐藏对象的工作细节 多态:可对不同类的对象使用同样的操作 在Python中类的继承定义基本 ...
- 例题-Quota 实作:
假设这五个用户均需要进行磁盘配额限制,每个用户的配额为 2GB (hard) 以及 1.8GB (soft),该如何处理? 答: 这一题实作比较难,因为必须要包括文件系统的支持.quota 数据文件建 ...
- Eclipse 3.7(代号Indigo) 中文字体太小解决办法(转)
升级到3.7Eclipse最直观的反映就是,中文怎么那么小啊---- 相当不方便. 其实这是Eclipse的默认字体换了,以前的一直是Courier New,现在修改字体也找不到了,算了不找了. 这次 ...
- C#: Create a WebRequest with HTTPClient
http://www.cnblogs.com/shanyou/archive/2012/03/21/2410739.html http://msdn.microsoft.com/zh-cn/libra ...