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. yui--datatable 行添加格式

    采用formatter YAHOO.widget.DataTable.Formatter.changeLight=function(elCell, oRecord, oColumn, oData){ ...

  2. php 环境搭建注意事项

    安装php 环境,最后安装集成环境,因为 apache+php 互联不是很容易. 这里主要是两个工具集成工具(wamp ,AppServ),其实这两个集成环境都包括(apache+mysql+php) ...

  3. Shell遍历文件的每一行

    由于使用for来读入文件里的行时,会自动把空格和换行符作为一样分隔符,因为当行里有空格的时候,输出的结果会很乱,所以…… cat input.txt |while read line> do&g ...

  4. Swift基础语法学习总结二

    1.函数 1.1 func funcNmae()->(){} 这样就定义了一个函数,它的参数为空,返回值为空,如果有参数和返回值直接写在两个括号里就可以了 1.2 参数需要指明类型,而如果没有返 ...

  5. java集合简介

    java集合主要包括以下几点 Java 集合概述 Collection 接口 Iterator 接口 Set List Map Collections 工具类 Enumeration 1.java集合 ...

  6. JSP元素和标签

    1.JSP 的运行原理  当服务器上的一个JSP 页面被第一次请求执行时,服务器上的JSP引擎首先将JSP 页面文件转译成一个java 文件,再将这个java 文件 编译生成字节码文件,然后通过执行字 ...

  7. js给页面加style

    今天做项目时遇到一个问题,我的a.jsp引入了b.jsp,c.jsp也引入了b.jsp,而b.jsp里面的style是根据引入的不同动态改变的(在a.jsp.c.jsp中写js改变).网上找了好多代码 ...

  8. ngnix 一 入门指南

    翻译自:ngnix--Beginner Guide ##ngnix入门指南 本指南给出了nginx的基本介绍,并介绍了可以使用它的完成一些简单任务. 它假定nginx已经安装在读者的机器上. 如果不是 ...

  9. Duplicate headers received from server

    This ones a little old but was high in the google ranking so I thought I would throw in the answer I ...

  10. 跟Google学习Android开发-起始篇-构建你的第一个应用程序(4)

    说明:此系列教程翻译自Google Android开发者官网的Training教程,利用Chome浏览器的自动翻译功能作初译,然后在一些语句不顺或容易造成误解的地方作局部修正.方便英文不好的开发者查看 ...