iOS开发教程-iOS中的RSA加解密

在移动应用开发中常常遇到数据传输安全性的问题,尤其是在账户安全以及支付场景中的订单数据、或支付信息的传输中,正规的公司一定会要求对数据进行加密,当然有创业初期的公司会在前期产品中让所有数据进行“裸奔”,不过在产品成型以后,一定会要求对数据进行加密的。那么,接下来就简单说说iOS中最常见的RSA加密吧。

RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。

RSA采用公开密钥密码体制。

所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。在实际工作中的加密密钥都是对多个加密端公开的,保证其安全性的主要任务是解密密钥的保密工作。

1.iOS中RSA加解密的密钥创建

首先要使用RSA加密,首先是生成RSA的加密密钥和解密密钥,

RSA是非对称加密方式,在实际应用中,

通常把用来加密的密钥称为公钥,

如在iOS端、Android、Windows Phone应用中加密数据使用的密钥,

解密密钥称为私钥,一般把解密密钥存放在移动应用的服务器端。

这种做法主要是考虑到心怀恶意的攻击者很容易获取移动端应用,进行反编译获取加密密钥,而攻击者想要获取服务器端的私钥(除非服务器端团队成员恶意泄露),否则基本上不可能,

而获取到RSA的加密密钥,只要密钥的位数足够长,几乎不可能推导出解密密钥,所以攻击者拿到加密密钥完全没有用。

在不同环境中有不同的创建RSA加密密钥和解密密钥的方法,下面提供一个在Mac系统中使用终端创建的具体步骤:

生成私钥文件
$ opensslgenrsa -out private.pem2048

◦openssl:是一个自由的软件组织,专注做加密和解密的框架。

genrsa:指定了生成了算法使用RSA

-out:后面的参数表示生成的key的输入文件

2048:表示的是生成key的长度,单位字节(bits)

创建证书请求
$ opensslreq -new -key private.pem -out rsacert.csr

可以拿着这个文件去数字证书颁发机构(即CA)申请一个数字证书。CA会给你一个新的文件cacert.pem,那才是你的数字证书。(要收费的)

生成证书并签名,有效期10年
$ openssl x509 -req -days 3650 -in rsacert.csr -signkeyprivate.pem -out
rsacert.crt

509是一种非常通用的证书格式。

将用上面生成的密钥privkey.pem和rsacert.csr证书请求文件生成一个数字证书rsacert.crt。这个就是公钥

转换格式将PEM 格式文件转换成DER 格式
$ openssl x509 -outform der -in rsacert.crt -out rsacert.der

在iOS开发中,公钥是不能使用base64编码的,上面的命令是将公钥的base64编码字符串转换成二进制数据

导出 P12 文件

在iOS使用私钥不能直接使用,需要导出一个p12文件。下面命令就是将私钥文件导出为p12文件。

$ openssl pkcs12
-export -out p.p12 -inkeyprivate.pem -in rsacert.crt

有了公钥和私钥之后,接下来的就是代码了,在这我粘贴出重要部分的代码,如果想要具体的Demo

2.加解密的方法声明

加密方法

+(NSString *)RSAEncrypt:(NSString *)plainTextString;

/**************************************************************************

函数名称: + (NSData
*)RSADecryptWithPrivateKey:(NSData*)cipherData

函数描述 : 用私钥对已经进行RSA加密的数据进行解密

输入参数: (NSData *)data

输出参数 : N/A

返回参数: (NSData *)

备注信息 :

******************************************************************************/

解密方法

/**************************************************************************

函数名称: +(NSString
*)RSADecryptString:(NSString *)rsaString

函数描述 : 用私钥对已经进行RSA加密的字符串进行解密

输入参数:(NSString *)rsaString

输出参数 : N/A

返回参数: (NSString *)

备注信息 :

**************************************************************************/

+(NSString *)RSADecryptString:(NSString *)rsaString;

3.加解密方法的具体实现

加密方法实现

+(NSString *)RSAEncrypt:(NSString *)plainTextString

{

if(!plainTextString || [plainTextStringisEqualToString:@"null"]){

return nil;

}

size_tcipherBufferSize = SecKeyGetBlockSize([self getPublicKey]);

uint8_t *cipherBuffer = malloc(cipherBufferSize);

uint8_t *nonce = (uint8_t *)[plainTextString UTF8String];

SecKeyEncrypt([self getPublicKey], kSecPaddingNone, nonce, strlen(
(char*)nonce ), &cipherBuffer[0], &cipherBufferSize);

NSData *encryptedData =
[NSDatadataWithBytes:cipherBufferlength:cipherBufferSize];

//将加密后的数据进行Base64编码并转化为NSString

return [encryptedData base64EncodedString];

}

4.解密方法实现

+(NSString *)RSADecryptString:(NSString *)rsaString

{

//将已经进行base64编码的字符串解码成普通的NSData

NSData *cipherData = [rsaString base64DecodedData];

NSData *plainData = [QFRSAToolRSADecryptWithPrivateKey:cipherData];

return [[NSStringalloc]initWithData:plainData
encoding:NSUTF8StringEncoding];

}

+ (NSData *)RSADecryptWithPrivateKey:(NSData *)cipherData {

// 分配内存块,用于存放解密后的数据段

size_tplainBufferSize = SecKeyGetBlockSize([QFRSAToolgetPrivateKey]);

NSLog(@"plainBufferSize = %zd", plainBufferSize);

uint8_t *plainBuffer = malloc(plainBufferSize * sizeof(uint8_t));

// 计算数据段最大长度及数据段的个数

doubletotalLength = [cipherData length];

size_tblockSize = plainBufferSize;

size_tblockCount = (size_t)ceil(totalLength / blockSize);

NSMutableData *decryptedData = [NSMutableData data]; // 分段解密

for (inti = 0; i<blockCount; i++) {

NSUIntegerloc = i * blockSize; // 数据段的实际大小。最后一段可能比blockSize小。

intdataSegmentRealSize = MIN(blockSize, totalLength - loc);

// 截取需要解密的数据段

NSData *dataSegment = [cipherDatasubdataWithRange:NSMakeRange(loc,
dataSegmentRealSize)];

OSStatus status = SecKeyDecrypt([QFRSAToolgetPrivateKey], kSecPaddingNone,
(const uint8_t *)[dataSegment bytes], dataSegmentRealSize, plainBuffer,
&plainBufferSize);

if (status == errSecSuccess) {

NSData *decryptedDataSegment = [[NSDataalloc] initWithBytes:(const void
*)plainBufferlength:plainBufferSize];

[decryptedDataappendData:decryptedDataSegment];

} else {

if (plainBuffer) {

free(plainBuffer);

}

return nil;

}

}

if (plainBuffer) {

free(plainBuffer);

}

returndecryptedData;

}

5.RSA的优点

安全性高,难于破解

6.RSA加密的缺点

1)产生密钥很麻烦,受到素数产生技术的限制,因而难以做到一次一密。

2)安全性,RSA的安全性依赖于大数的因子分解,但并没有从理论上证明破译RSA的难度与大数分解难度等价,而且密码学界多数人士倾向于因子分解不是NP问题。现今,人们已能分解140多个十进制位的大素数,这就要求使用更长的密钥,速度更慢;另外,人们正在积极寻找攻击RSA的方法,如选择密文攻击,一般攻击者是将某一信息作一下伪装(Blind),让拥有私钥的实体签署。然后,经过计算就可得到它所想要的信息。实际上,攻击利用的都是同一个弱点,即存在这样一个事实:乘幂保留了输入的乘法结构:

(XM)d =
Xd *Md mod n

前面已经提到,这个固有的问题来自于公钥密码系统的最有用的特征--每个人都能使用公钥。但从算法上无法解决这一问题,主要措施有两条:一条是采用好的公钥协议,保证工作过程中实体不对其他实体任意产生的信息解密,不对自己一无所知的信息签名;另一条是决不对陌生人送来的随机文档签名,签名时首先使用One-Way
Hash Function对文档作HASH处理,或同时使用不同的签名算法。除了利用公共模数,人们还尝试一些利用解密指数或φ(n)等等攻击.

3)速度太慢,由于RSA 的分组长度太大,为保证安全性,n 至少也要
600 bits以上,使运算代价很高,尤其是速度较慢,较对称密码算法慢几个数量级;且随着大数分解技术的发展,这个长度还在增加,不利于数据格式的标准化。SET(Secure
Electronic Transaction)协议中要求CA采用2048比特长的密钥,其他实体使用1024比特的密钥。为了速度问题,人们广泛使用单,公钥密码结合使用的方法,优缺点互补:单钥密码加密速度快,人们用它来加密较长的文件,然后用RSA来给文件密钥加密,极好的解决了单钥密码的密钥分发问题。

RSA 加密的更多相关文章

  1. “不给力啊,老湿!”:RSA加密与破解

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 加密和解密是自古就有技术了.经常看到侦探电影的桥段,勇敢又机智的主角,拿着一长串毫 ...

  2. .NET 对接JAVA 使用Modulus,Exponent RSA 加密

    最近有一个工作是需要把数据用RSA发送给Java 虽然一开始标准公钥 net和Java  RSA填充的一些算法不一样 但是后来这个坑也补的差不多了 具体可以参考 http://www.cnblogs. ...

  3. Android数据加密之Rsa加密

    前言: 最近无意中和同事交流数据安全传输的问题,想起自己曾经使用过的Rsa非对称加密算法,闲下来总结一下. 其他几种加密方式: Android数据加密之Rsa加密 Android数据加密之Aes加密 ...

  4. 兼容javascript和C#的RSA加密解密算法,对web提交的数据进行加密传输

    Web应用中往往涉及到敏感的数据,由于HTTP协议以明文的形式与服务器进行交互,因此可以通过截获请求的数据包进行分析来盗取有用的信息.虽然https可以对传输的数据进行加密,但是必须要申请证书(一般都 ...

  5. RSA加密例子和中途遇到的问题

    在进行RSA加密例子 package test; import java.io.IOException; import java.security.Key; import java.security. ...

  6. iOS中RSA加密详解

    先贴出代码的地址,做个说明,因为RSA加密在iOS的代码比较少,网上开源的也很少,最多的才8个星星.使用过程中发现有错误.然后我做了修正,和另一个库进行了整合,然后将其支持CocoaPod. http ...

  7. iOS动态部署之RSA加密传输Patch补丁

    概要:这一篇博客主要说明下iOS客户端动态部署方案中,patch(补丁)是如何比较安全的加载到客户端中. 在整个过程中,需要使用RSA来加密(你可以选择其它的非对称加密算法),MD5来做校验(同样,你 ...

  8. Java使用RSA加密解密及签名校验

    该工具类中用到了BASE64,需要借助第三方类库:javabase64-1.3.1.jar注意:RSA加密明文最大长度117字节,解密要求密文最大长度为128字节,所以在加密和解密的过程中需要分块进行 ...

  9. 基于OpenSLL的RSA加密应用(非算法)

    基于OpenSLL的RSA加密应用(非算法) iOS开发中的小伙伴应该是经常用der和p12进行加密解密,而且在通常加密不止一种加密算法,还可以加点儿盐吧~本文章主要阐述的是在iOS中基于openSL ...

  10. 通过ios实现RSA加密和解密

    在加密和解密中,我们需要了解的知识有什么事openssl:RSA加密算法的基本原理:如何通过openssl生成最后我们需要的der和p12文件. 废话不多说,直接写步骤: 第一步:openssl来生成 ...

随机推荐

  1. Symmetric Tree——LeetCode

    Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). For e ...

  2. typedef 用法及 指针函数 和 函数指针

    typedef 本质上是定义了一种新的类型, 该新类型可以原有类型的别名或是原有类型的组合. 而#define 只是字符串的替换. 如定义: typedef char* CHARP; 则 CHARP ...

  3. HDU_1874——最短路问题,Dijkstra算法模版

    Problem Description 某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行 ...

  4. C++ —— 类的基础

    C++类的设计与基础       2015.9.11 1.变量和常量的命名:确定程序中的变量.常量.函数的名字都是具有描述性的名字,具有直接的意义.如numberOfStudent 比 numOfSt ...

  5. JavaScript MVC 框架[转载]

    MVC,MVP 和 MVVM 的图示 http://www.ruanyifeng.com/blog/2015/02/mvcmvp_mvvm.html http://blog.nodejitsu.com ...

  6. 单页面应用SPA架构

    个人认为单页面应用的优势相当明显: 前后端职责分离,架构清晰:前端进行交互逻辑,后端负责数据处理. 前后端单独开发.单独测试. 良好的交互体验,前端进行的是局部渲染.避免了不必要的跳转和重复渲染. 当 ...

  7. Android 面试精华题目总结

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24015867 下面的题目都是楼主在android交流群大家面试时遇到的,如果大家 ...

  8. Java基础知识强化之集合框架笔记01:集合的由来与数组的区别

    1. 集合的由来: 我们学习的是面向对象语言,而面向对象语言对事物的描述是通过对象体现的,为了方便对多个对象进行操作,我们就必须把这多个对象进行存储.而要想存储多个对象,就不能是一个基本的变量,而应该 ...

  9. python 整型--《Python 3程序开发指南》笔记

    参考:<Python 3程序开发指南> 整数转换函数: bin(i) 返回整数i的二进制表示(字符串) hex(i) 返回i的十六进制表示(字符串) int(x) 将x转换为整数,失败产生 ...

  10. http方式的联调经验

    这近在做一个项目,现在刚与厂家做联调.我的系统是windows2008,他的测试机是unix,他本机是XP的.本来用httppost方式给他本机发送中文数据是正常的,但是发送到他的unix上,中文就变 ...