RSAObjC 0.1.1

RSAObjC 0.1.1

lifei 维护。



RSAObjC 0.1.1

  • 作者
  • lifei

CI Status Version License Platform

RSA 可以说是 iOS 端使用最多、最广泛的非对称加密算法,尽管近年来我国基于安全和宏观战略考虑,推出了我国自主知识产权的非对称加密算法 SM2,但使用率和普及率还远不及 RSA。国密 SM2 加解密可参考另一个项目 GMObjC

快速开始

在终端运行以下命令,可查看 Demo:

git clone https://github.com/muzipiao/RSAObjC.git

cd RSAObjC/Example

pod install

open RSAObjC.xcworkspace

集成

CocoaPods

CocoaPods 是最简单、最方便的集成方式。编辑 Podfile 文件,添加:

pod 'RSAObjC'

然后执行 pod install 即可。

直接集成

从 Git 下载最新代码,找到与 README 同级的 RSAObjC 文件夹,将 RSAObjC 文件夹拖入项目,并在项目中添加 Security.framework 框架,在需要使用的地方导入头文件 RSAObjC.h 即可使用 RSA 加解密。

用法

最常用的就是后台返回公钥字符串,加密密码后返回给后台,使用工具类进行加解密都很简单。

//----------------------RSA 加密示例------------------------
// 原始数据,要加密的字符串
NSString *originalString = @"这是一段将要使用'秘钥字符串'进行加密的字符串!";

// RSA 加密,使用字符串格式的公钥私钥加密解密, RSAPublickKey  为公钥字符串(NSString 格式)
NSString *encryptStr = [RSAObjC encrypt:originalString PublicKey:RSAPublickKey];
NSLog(@"加密后:%@", encryptStr);

// RSA 解密,用私钥解密,RSAPrivateKey 为私钥字符串(NSString 格式)
NSString *decryptStr = [RSAObjC decrypt:encryptStr PrivateKey:RSAPrivateKey];
NSLog(@"解密后:%@",decryptStr);

其他

RSA 加密在 iOS 中经常用到,较复杂的做法是使用 openssl 生成所需的秘钥文件,需要用到 .der 和 .p12 格式的文件,其中 .der 格式的文件存放的是公钥(Public key)用于加密,.p12 格式的文件存放的是私钥(PrivateKey)用于解密。

公钥和私钥的关系,有人把公钥比喻为保险箱,把私钥比喻为保险箱的钥匙,保险箱我可以给任何人,也可以有多个保险箱,任何人都可以往保险箱里面放东西(机密数据),但只有我有私钥(保险箱的钥匙),只有我能打开保险箱。

常用场景

最常见的场景是客户端向服务端发送密码的场景,客户端先从服务端获取公钥,加密密码后发送。

常用场景

以下是一个密码验证流程示例,iPhone 表示客户端,Server 表示服务端。

iPhone->Server: 客户端向服务请求 RSA 公钥
Server: 服务端保留 RSA 私钥
Server-->iPhone: 服务端将 RSA 公钥发送给客户端
iPhone: 客户端使用 RSA 公钥加密密码
iPhone->Server: 客户端将加密后的密文发送给服务器
Server: 服务端使用 RSA 私钥解密校验密码
Server-->iPhone: 服务端将密码校验结果发送给客户端

关于特殊字符网络传输转义的问题

这是一串由服务器生成的 RSA 公钥,可以看到它由数字、字母及 +/ 组成。

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDTbZ6cNH9
PgdF60aQKveLz3FTalyzHQwbp601y77SzmGHX3F5NoVUZbd
K7UMdoCLK4FBziTewYD9DWvAErXZo9BFuI96bAop8wfl1Vk
ZyyHTcznxNJFGSQd/B70/ExMgMBpEwkAAdyUqIjIdVGh1FQ
K/4acwS39YXwbS+IlHsPSQIDAQAB

由于含有 /+=\n 等特殊字符串,网络传输过程中导致转义,进而导致加密解密失败,解决办法是进行 URL 特殊符号编码解码(百分号转义),如下所示,将除字母数字外的所有符号进行 URLEncode 编码。

/**
 * self.gPubkey 是如上所示公钥
 * alphanumericCharacterSet 表示字母数字字符集
 */
NSString *encodePubKey = [self.gPubkey stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.alphanumericCharacterSet];

// 解码更简单,stringByRemovingPercentEncoding 即可 URLDecode
NSString *decodePubKey = encodePubKey.stringByRemovingPercentEncoding;

编码后如下所示,除了字母数字外,其他符号都变成了 URLEncode 形式,解码后与原文相同。

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDTbZ6cNH9
PgdF60aQKveLz3FTalyzHQwbp601y77SzmGHX3F5NoVUZbdK7U
MdoCLK4FBziTewYD9DWvAErXZo9BFuI96bAop8wfl1VkZyyHTczn
xNJFGSQd%2FB70%2FExMgMBpEwkAAdyUqIjIdVGh1FQK%2F4
acwS39YXwbS%2BIlHsPSQIDAQAB

OpenSSL 生成公私钥

在 Mac 上使用 OpenSSL 生成公私钥进行测试,位数可选 1024、2048、4096 等,位数越大,生成的公私钥越长,安全性越高,但加解密速度也会越慢。注意,如果传入 PEM 格式公私钥,私钥必须为 PKCS8 格式。

# 生成 2048 位 RSA 私钥
openssl genrsa -out rsa_private_key.pem 2048

# 生成成对的 2048 位 RSA 公钥
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

# 将 RSA 私钥转换为 PKCS8 格式
openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt > rsa_private_key_pkcs8.pem

然后就可以使用公钥文件 rsa_public_key.pem 和私钥文件 rsa_private_key_pkcs8.pem 进行加密解密。

如果您觉得有所帮助,请在 GitHub RSAObjC 上点个 Star。⭐️,您的鼓励是我前进的动力