背景

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加解密的更多相关文章

  1. java与IOS之间的RSA加解密

    很简单的一个需求,ipad端给密码RSA加密,传到java后台,解密.RSA加密算法是基于一个密钥对的,分为公钥和私钥,一般情况公钥加密,私钥解密,但也可私钥加密,公钥解密.还可以验签,就是先用私钥对 ...

  2. OpenSSL RSA加解密 (.Net公钥加密/ Linux端私钥解密)

    要求在.Net端生成公钥私钥对. 然后在.Net端使用RSA公钥加密:在Linux端使用RSA私钥解密. 最初的尝试是:.Net端使用RSACryptoServiceProvider; linux端使 ...

  3. 全面解决.Net与Java互通时的RSA加解密问题,使用PEM格式的密钥文件

    作者: zyl910 一.缘由 RSA是一种常用的非对称加密算法.所以有时需要在不用编程语言中分别使用RSA的加密.解密.例如用Java做后台服务端,用C#开发桌面的客户端软件时. 由于 .Net.J ...

  4. 前后端java+vue 实现rsa 加解密与摘要签名算法

    RSA 加密.解密.签名.验签.摘要,前后端java+vue联调测试通过 直接上代码 // 注意:加密密文与签名都是唯一的,不会变化.// 注意:vue 端密钥都要带pem格式.java 不要带pem ...

  5. java RSA加解密以及用途

    在公司当前版本的中间件通信框架中,为了防止非授权第三方和到期客户端的连接,我们通过AES和RSA两种方式的加解密策略进行认证.对于非对称RSA加解密,因为其性能耗费较大,一般仅用于认证连接,不会用于每 ...

  6. RSA算法原理——(3)RSA加解密过程及公式论证

    上期(RSA简介及基础数论知识)为大家介绍了:互质.欧拉函数.欧拉定理.模反元素 这四个数论的知识点,而这四个知识点是理解RSA加密算法的基石,忘了的同学可以快速的回顾一遍. 一.目前常见加密算法简介 ...

  7. RSA加解密用途简介及java示例

    在公司当前版本的中间件通信框架中,为了防止非授权第三方和到期客户端的连接,我们通过AES和RSA两种方式的加解密策略进行认证.对于非对称RSA加解密,因为其性能耗费较大,一般仅用于认证连接,不会用于每 ...

  8. RSA加解密&RSA加验签详解

    RSA 加密算法是目前最有影响力的 公钥加密算法,并且被普遍认为是目前 最优秀的公钥方案 之一.RSA 是第一个能同时用于 加密 和 数字签名 的算法,它能够 抵抗 到目前为止已知的 所有密码攻击,已 ...

  9. Rsa加解密Java、C#、php通用代码 密钥转换工具

    之前发了一篇"TripleDes的加解密Java.C#.php通用代码",后面又有项目用到了Rsa加解密,还是在不同系统之间进行交互,Rsa在不同语言的密钥格式不一样,所以过程中主 ...

随机推荐

  1. javascript refresh page 几种页面刷新的方法

    Javascript刷新页面的几种方法:1    history.go(0) 2    location.reload() 3    location=location 4    location.a ...

  2. 使用 Visual Studio Team Test 进行单元测试和java中的测试

    C#中test测试地 方法一. 1.从NUnit官网(http://www.nunit.org/index.php)下载最新版本NUnit,当前版本为NUnit2.5.8. 2.安装后,在VS2008 ...

  3. 基于WCF的API实现

    本文程序基于VS2013.EF6.1.WCF WCF有2种方式,一是SOAP,一种是Restful 由于程序是基于PCL(可移植类库)的,所以不能用直接引入WCF服务的方式 网上的Restful方式的 ...

  4. 菜鸟学习Struts——配置Struts环境

    刚开始学习Struts,它通过采用JavaServlet/JSP技术,实现了基于Java EEWeb应用的MVC设计模式的应用框架,是MVC经典设计模式中的一个经典产品. 要用到Struts就要学会配 ...

  5. swift UIAlertController教程

    在iOS8中,UIAlertView与UIActionSheet都已经退休,取而代之的是UIAlertController!它的使用示范如下://弹出一个警告框,标题是“提示”,信息是“我的博客:oa ...

  6. Entity Framework(一) 映射

    ADO.NET Entity Framework通过Modeel First和DataBase First,提供了几个把数据库表映射到对象上的曾.通过Database First,可以从一个数据库架构 ...

  7. 多路选择器(multiplexer)简介

    1.多路器简介 简称:多路器 功能:多输入  单输出   组合逻辑电路 2.verilog代码实现: module Mux_8(addr,in1,in2,in3,in4,in5,in6,in7,in8 ...

  8. CS0016: 未能写入输出文件的解决方法

    编译器错误消息: CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework\v2.0.50727 \Temporary ASP.NET Files\roo ...

  9. 团队项目之Sprint计划会议

    一.我们团队在4月15日进行了冲刺计划会议,会议过程大致如下: 1.总结目前的工作进展,再一次确定所做项目的方向: 2.将之前的调查问卷的结果进行统计,做了需求分析,大致了解了用户的想法: 3.根据初 ...

  10. beego 0.9.0 中智能路由AutoRouter的使用方法及源码解读

    了解beego的开发者肯定知道,beego的路由设计来源于sinatra,原来是不支持自动路由的,每一个路由都要自己配置的,如: type MainController struct { beego. ...