内容简介:契机是公司换了一套新接口,要求进行全报文加密。以前公司项目基本上都使用的对称加密的模式本篇不会对1.
1.前言
契机是公司换了一套新接口,要求进行全报文加密。以前公司项目基本上都使用的对称加密的模式 3DES
、 AES
,由于对称加密的密钥只有一对,有很大的密钥泄露风险。身处金融这个极为敏感的行业,对安全的要求也是极高。趁着这个机会,把项目中的加密模式统一替换成 RSA
非对称加密。
2.关于加密算法
本篇不会对 RSA
加密算法原理进行详细的解释。在互联网异常发达的今天, RSA
算法详细的资料很容易就能获取到。安全领域也是一个能够深挖的领域,本篇文章偏向工程向,仅对一些基本基本概念进行简单的解释。
- 对称加密和非对称加密
1. 对称加密 :加密和解密用的是同一套密钥,缺陷是密钥管理存在风险。常用的加密方式有: DES
、 3DES
、 AES
等。
2. 非对称加密 :加密和解密用的不同的密钥,公钥加密私钥解密。常用的加密方式有 RSA
。
- RSA常见用法 :
1. 公钥加密,私钥解密;
2. 私钥签名;
3. 公钥验签。
3.实践
1、生成密钥:
使用终端openssl命令生成密钥
1).生成私钥,密钥长度为2048bit,base64编码。
openssl genrsa -out rsa_private_key.pem 2048 复制代码
关于密钥长度,这里要进行一下特别说明。每次加密的数据不能超出密钥的长度,2048bit长度的密钥,只能单次只能加密(2048 / 8 - 11) = 245byte长度的数据。(那11byte是RSA预留的长度)。若待加密的数据长度超过了245byte,就需要对数据进行分段加密。
2).根据之前生成的私钥生成公钥:
openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout 复制代码
3).转换公钥为 PKCS8
格式,这种格式可以直接在iOS项目中使用:
openssl pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt 复制代码
我司的情况是由公司后台生成私钥和公钥,提供 .pem
格式的公钥给移动端,因此我直接使用的是pkcs8格式的公钥。
注意:不建议将私钥保存在客户端,私钥泄露后果会很严重!
2、在项目中使用:
Demo地址: github.com/Hstripe/RHR…
以上是我使用的 RSA
工具类,支持 RSA
在移动端的各种日常用法:加密、解密、加签、验签。跟网上很多 工具 类不同的是不需要导入 p12
、 der
格式的密钥文件,支持字符串形式的密钥文件非常方便。而且使用的是 Apple
自家的 Security.framework
。网上很多例程都是使用的 openSSL
那一套加密工具类,实现也很方便就是包体积略微有点大。
若使用 IDE
是 Xcode8
及以上,请在 Capabilities
中将 KeyChain sharing
设置为 YES
1.)公钥加密
NSString *string = @"doRSAEncrypt"; NSString *publickey = @"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA61sODmFj/OXnrHUYzams\ c/6XLni9G0HYv9sBewaPjF6qlu845nwmYSA6dQ9zPk231o5l3tmHLpUQGNnp/5rH\ +84iB/tM+Y+2kTI8uILGbmby2DL3rgzBG+I9h7e3w3QktpdcD8Z+ZuEVa/CY3Xez\ 8X1uknEVzIIhDKY7ipAoebchVdELbTlH1BRLz8RH6mQ+Z8REH4UL0TiQLfSfTotv\ 1G5ZerNxVZ7Toi4K9KFDA+1UD+LeDGg8PY/sdg0AJpR4o6bfDBko50wKLDz4UYyp\ 7EFZv661o2Mr7+KoQ6Tpb7w8bTl7wrRKz9ugB5+tM2F7aDvv1mzr7STIF+2c7tEx\ DQIDAQAB"; NSString *encryptString = [IPNRSAUtil encryptString:string publicKey:publickey]; 复制代码
2.)私钥解密
NSString *privatekey = @"MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDrWw4OYWP85ees\ dRjNqaxz/pcueL0bQdi/2wF7Bo+MXqqW7zjmfCZhIDp1D3M+TbfWjmXe2YculRAY\ 2en/msf7ziIH+0z5j7aRMjy4gsZuZvLYMveuDMEb4j2Ht7fDdCS2l1wPxn5m4RVr\ 8Jjdd7PxfW6ScRXMgiEMpjuKkCh5tyFV0QttOUfUFEvPxEfqZD5nxEQfhQvROJAt\ 9J9Oi2/Ubll6s3FVntOiLgr0oUMD7VQP4t4MaDw9j+x2DQAmlHijpt8MGSjnTAos\ PPhRjKnsQVm/rrWjYyvv4qhDpOlvvDxtOXvCtErP26AHn60zYXtoO+/WbOvtJMgX\ 7Zzu0TENAgMBAAECggEBAOMf6w+ror9y6sE9+6K1hEwoO6NIN06vm8mCQwqDiVIw\ JTYlQ+cBllQSsvc24sMUYz32C48ko1Ur2u3wleXqa+Wvxp2nQWBw9QFn1rtE0NPI\ G8DSZr0bZ9xN1406mWdQlQF0Tg6XQnJr8q1I8WyAUTHSFzvRT/Uc+2Hmpf0RI05Y\ t0dt5bsGn/g+ijGbCm63Z2U8u5yWXidxWfU/KyYf1Y3mw9lGLR6IJc/q9N+TO4ih\ JM5pCraMFI4zWblGobkN2WKy7MrQ45FLSKul4W00+VyM/rVivW/fYUaqFEnlBog3\ /4hgI6Bsw2IuSk2Ubhbc4fp//146vJf6oL4WAJHmAiECgYEA+e3AFph8joC5gC1Q\ ok97tLJqt95fZCx4VCw6lPPbWxOHG6TJlvlo7kZIeUfKrGIlOWn38yuw5thEZKwW\ bzE8kn5WGlUgkOQ7hJ6Iiw/TzCFPRHxV63WBKa8OnyFIn3w91zI8ZTcUgrgyns+F\ gE5uxkEjb6iIyxxnpqC7Fk3lnikCgYEA8RKtn7kqoe0T/Yv7UsPLm7KzuWn3/01r\ LGA+x+GCp4rP2Lf0u1K+7VY6Dv/ceTBuA/2Yujenkjt0LaF+Bz0tLWFB5BTw3n+u\ 6QshVdP3O1im4w6p3e8O9mfBCSV/CX5oBkbamemyQ7DTB9VtYNNmtGTs2aySuoel\ zPU0czETEEUCgYAjVhwclb62nzibCM0nxbkl2TwBdy1hinAQ5pf5y2iuPdqSbAAc\ mnLdjY5dp2reaJn+vh7SgNDoMpeo7DPX0MxRog8mdfa+xaYsoAWKM9isOeFtO28i\ dWCnthqJITmVYwmTTYUAgoMh4E036vtjIrPC0B7kgJ2mqgN1qbAJ/UWD0QKBgFSO\ U53hacWwDUHydm2aRXFQJd/T/mtq8Tt4aqzbOWOgubRvGYUWyecfRm/6aI+NYBlA\ OvCeEsWk2uQib70ERTNUmLLycWXpbSVKhR/AoEgNmUOs4gH5FstwqvGVWFCxKLWC\ 5qvzn1ZE0FBAGQRMQgrmF3lmIXURnSMdoo8A2IntAoGAVCFmPpXvI8rMk2N3CvQ4\ dkDfP3W6w1KpyMzuQRZE9N1IUBYh3KN25HfzeW1OIFHPuxInMm/6zaU/rUHJSy/b\ ynVdQ6jvM4ZIt3rYUXZN6+a14AeA/MNNrY2LzCYlCxWIbVyNj9UN8/uda0zEtZ73\ RWYX1BlKVMSIx5Bf7eNH4fI="; NSString *decryptString = [IPNRSAUtil decryptString:encryptString privateKey:privatekey]; 复制代码
3.)私钥加签
NSString *signature = [IPNRSAUtil rsaSignString:string WithPrivateKey:privatekey]; 复制代码
4.)公钥验签
BOOL result = [IPNRSAUtil rsaVerifySignature:signature plainString:string WithPublicKey:publickey]; 复制代码
5.)分段加密
若待加密的数据长度大于密钥长度,就需要对待加密的数据进行分段加密
// n为密钥单次加密长度,这里使用的是2048位的密钥,因此n的值为245(2048/8 - 11)。 NSInteger n = 245; NSMutableData *preData = [[NSMutableData alloc] init]; for (NSInteger i=0; i<=ceilf(string.length / n); i++) { NSString *subString = [string substringWithRange:NSMakeRange(i * n, MIN(n, string.length - i * 245))]; NSData *encryptData = [IPNRSAUtil encryptData:[subString dataUsingEncoding:NSUTF8StringEncoding] publicKey:publickey]; // 分段加密需要拼接加密后的data数据,不要将data转换成字符串再拼接,这样会导致结果错误。 [preData appendData:encryptData]; } NSData *finalData = [[NSData alloc] initWithData:preData]; finalData = [finalData base64EncodedDataWithOptions:0]; NSString *result = [[NSString alloc] initWithData:finalData encoding:NSUTF8StringEncoding]; 复制代码
4.后记
为了搞这个工具类前前后后花了也有半个多月的时间了,看了很多文档和例程加上自己的实践调试才有了这个工具类。一开始使用的是 openSSL
那一套加密工具实现的,但是觉得 openSSL
占用的空间略大,还是用 Security.framework
来实现的。平时总是忙于业务需求的实现,忽视了客户端方面的安全,网上对客户端安全这一块的资源也比较有限,但愿我这篇文章能对后来人有所帮助吧。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Python算法引入
- 微软在Azure上引入以太坊认证算法
- 破解信息茧房,算法推荐需要引入“父爱式”传播
- [译][译]C++17,标准库新引入的并行算法
- 通用电气为算法引入业务风险考量,试用“谦逊人工智能”
- 机器学习算法 Java 库 Smile 1.5.0 发布,引入新特性
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。