一: 原理
1. 什么是RSA?
RSA是一种非对称加密算法,常用来对传输数据进行加密,配合上数字摘要算法,也可以进行文字签名。
2. RSA加密中padding?
padding即填充方式,由于RSA加密算法中要加密的明文是要比模数小的,padding就是通过一些填充方式来限制明文的长度。后面会详细介绍padding的几种模式以及分段加密。
3. 加密和加签有什么区别?
加密:公钥放在客户端,并使用公钥对数据进行加密,服务端拿到数据后用私钥进行解密;
加签:私钥放在客户端,并使用私钥对数据进行加签,服务端拿到数据后用公钥进行验签。
前者完全为了加密;后者主要是为了防恶意攻击,防止别人模拟我们的客户端对我们的服务器进行攻击,导致服务器瘫痪。
4. 基本原理
RSA使用“密钥对”对数据进行加密解密,在加密解密前需要先生存公钥(Public Key)和私钥(Private Key)。
公钥(Public key): 用于加密数据. 用于公开, 一般存放在数据提供方, 例如iOS客户端。
私钥(Private key): 用于解密数据. 必须保密, 私钥泄露会造成安全问题。
iOS中的Security.framework提供了对RSA算法的支持,这种方式需要对密匙对进行处理, 根据public key生成证书, 通过private key生成p12格式的密匙
二: 秘钥的生成方法
首先我们要会生成RSA密钥文件,现在一步步的来给大家展示一下,如何生成我们所需的公钥和私钥文件:
* 生成私钥文件
$ openssl genrsa -out private.pem 1024
openssl:是一个自由的软件组织,专注做加密和解密的框架。
genrsa:指定了生成了算法使用RSA
-out:后面的参数表示生成的key的输入文件
1024:表示的是生成key的长度,单位字节(bits)
* 创建证书请求
$ openssl req -new -key private.pem -out rsacert.csr
可以拿着这个文件去数字证书颁发机构(即CA)申请一个数字证书。CA会给你一个新的文件cacert.pem,那才是你的数字证书。(要收费的)
* 生成证书并签名,有效期10年
$ openssl x509 -req -days 3650 -in rsacert.csr -signkey private.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 -inkey private.pem -in rsacert.crt
三: iOS 中的使用注意
IOS客户端的加解密首先我们需要导入Security.framework,
在ios中,我们主要关注四个函数
SecKeyEncrypt:使用公钥对数据进行加密
SecKeyDecrypt:使用私钥对数据进行解密
SecKeyRawVerify:使用公钥对数字签名和数据进行验证,以确认该数据的来源合法性。什么是数字签名,可以参考百度百科这篇文章?
SecKeyRawSign:使用私钥对数据进行摘要并生成数字签名
RSA算法有2个作用一个是加密一个是加签。从这几个函数中,我们可以看到,我们第一种是使用公钥能在客户端:加密数据,以及服务器端用私钥解密。
第二个就是用私钥在客户端加签,然后用公钥在服务器端用公钥验签。第一种完全是为了加密,第二种是为了放抵赖,就是为了防止别人模拟我们的客户端来攻击我们的服务器,导致瘫痪。
1.RSA加密解密:
(1)获取密钥,这里是产生密钥,实际应用中可以从各种存储介质上读取密钥 (2)加密 (3)解密
2.RSA签名和验证
(1)获取密钥,这里是产生密钥,实际应用中可以从各种存储介质上读取密钥 (2)获取待签名的Hash码 (3)获取签名的字符串 (4)验证
3.公钥与私钥的理解:
(1)私钥用来进行解密和签名,是给自己用的。
(2)公钥由本人公开,用于加密和验证签名,是给别人用的。
(3)当该用户发送文件时,用私钥签名,别人用他给的公钥验证签名,可以保证该信息是由他发送的。当该用户接受文件时,别人用他的公钥加密,他用私钥解密,可以保证该信息只能由他接收到。
使用事例:
- (void)test
{
XYRSACryption *_rsa = [XYRSACryption new];
// 加载公钥
NSString *derPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"public_key" ofType:@"der"];
[_rsa loadPublicKeyFromFile:derPath];
// 加载私钥
NSString *p12Path = [[NSBundle bundleForClass:[self class]] pathForResource:@"private_key" ofType:@"p12"];
[_rsa loadPrivateKeyFromFile:p12Path password:@"123456"];
NSString *enStr = @"这里放置你要加密的文本内容!";
// 加密后的数据
NSData *enData = [_rsa rsaEncryptData:
[enStr dataUsingEncoding:NSUTF8StringEncoding]];
NSString *proStr = [[NSString alloc] initWithData:enData encoding:NSUTF8StringEncoding];
// 解密后的数据
NSData *deData = [_rsa rsaDecryptData:enData];
NSString *deStr = [[NSString alloc] initWithData:deData encoding:NSUTF8StringEncoding];
// 签名
NSData *signedData = [_rsa sha256WithRSA:enData];
// 对前面进行验证
BOOL result = [_rsa rsaSHA256VertifyingData:enData withSignature:signedData];
}
网友评论