iOS-在項(xiàng)目中使用RSA算法

封面圖

在正文開始之前先吐個(gè)槽城侧,看自己簡書上一篇發(fā)文已經(jīng)是好幾個(gè)月之前的了。之前的設(shè)想是每周輸出一篇技術(shù)方面的文檔域醇,接著就被硬生生拖成了一個(gè)月滚澜,然后就不知道幾個(gè)月去了......其間還是有有不少可以寫的題材,都是因?yàn)檫@該死的拖延~~~好了進(jìn)入正題蜕乡。

1.前言

契機(jī)是公司換了一套新接口奸绷,要求進(jìn)行全報(bào)文加密。以前公司項(xiàng)目基本上都使用的對稱加密的模式3DES层玲、AES号醉,由于對稱加密的密鑰只有一對,有很大的密鑰泄露風(fēng)險(xiǎn)辛块。身處金融這個(gè)極為敏感的行業(yè)畔派,對安全的要求也是極高。趁著這個(gè)機(jī)會憨降,把項(xiàng)目中的加密模式統(tǒng)一替換成RSA非對稱加密父虑。

2.關(guān)于加密算法

本篇不會對RSA加密算法原理進(jìn)行詳細(xì)的解釋该酗。在互聯(lián)網(wǎng)異常發(fā)達(dá)的今天授药,RSA算法詳細(xì)的資料很容易就能獲取到士嚎。安全領(lǐng)域也是一個(gè)能夠深挖的領(lǐng)域,本篇文章偏向工程向悔叽,僅對一些基本基本概念進(jìn)行簡單的解釋莱衩。

  • 對稱加密和非對稱加密
    對稱加密 :加密和解密用的是同一套密鑰,缺陷是密鑰管理存在風(fēng)險(xiǎn)娇澎。常用的加密方式有:DES笨蚁、3DESAES等趟庄。
    非對稱加密 :加密和解密用的不同的密鑰括细,公鑰加密私鑰解密。常用的加密方式有RSA戚啥。

  • RSA常見用法
    1.公鑰加密奋单,私鑰解密;
    2.私鑰簽名;
    3.公鑰驗(yàn)簽猫十。

3.實(shí)踐

1览濒、生成密鑰:

使用終端openssl命令生成密鑰

1).生成私鑰,密鑰長度為2048bit,base64編碼拖云。

openssl genrsa -out rsa_private_key.pem 2048

關(guān)于密鑰長度贷笛,這里要進(jìn)行一下特別說明。每次加密的數(shù)據(jù)不能超出密鑰的長度宙项,2048bit長度的密鑰乏苦,只能單次只能加密(2048 / 8 - 11) = 245byte長度的數(shù)據(jù)。(那11byte是RSA預(yù)留的長度)尤筐。若待加密的數(shù)據(jù)長度超過了245byte邑贴,就需要對數(shù)據(jù)進(jìn)行分段加密。

2).根據(jù)之前生成的私鑰生成公鑰:

openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout

3).轉(zhuǎn)換公鑰為PKCS8格式叔磷,這種格式可以直接在iOS項(xiàng)目中使用:

openssl pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt

我司的情況是由公司后臺生成私鑰和公鑰拢驾,提供.pem格式的公鑰給移動(dòng)端,因此我直接使用的是pkcs8格式的公鑰改基。

注意:不建議將私鑰保存在客戶端繁疤,私鑰泄露后果會很嚴(yán)重!

2秕狰、在項(xiàng)目中使用:

Demo地址:https://github.com/Hstripe/RHRSAUtil

以上是我使用的RSA工具類稠腊,支持RSA在移動(dòng)端的各種日常用法:加密、解密鸣哀、加簽架忌、驗(yàn)簽。跟網(wǎng)上很多工具類不同的是不需要導(dǎo)入p12我衬、der格式的密鑰文件叹放,支持字符串形式的密鑰文件非常方便饰恕。而且使用的是Apple自家的Security.framework。網(wǎng)上很多例程都是使用的openSSL那一套加密工具類井仰,實(shí)現(xiàn)也很方便就是包體積略微有點(diǎn)大埋嵌。

若使用IDEXcode8及以上,請?jiān)?code>Capabilities中將KeyChain sharing設(shè)置為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.)公鑰驗(yàn)簽

BOOL result = [IPNRSAUtil rsaVerifySignature:signature plainString:string WithPublicKey:publickey];

5.)分段加密

若待加密的數(shù)據(jù)長度大于密鑰長度,就需要對待加密的數(shù)據(jù)進(jìn)行分段加密

// 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數(shù)據(jù)合是,不要將data轉(zhuǎn)換成字符串再拼接了罪,這樣會導(dǎo)致結(jié)果錯(cuò)誤。
[preData appendData:encryptData];
}

NSData *finalData = [[NSData alloc] initWithData:preData];
finalData = [finalData base64EncodedDataWithOptions:0];
NSString *result = [[NSString alloc] initWithData:finalData encoding:NSUTF8StringEncoding];
NSLog(@"result:%@",result);
}

4.后記

為了搞這個(gè)工具類前前后后花了也有半個(gè)多月的時(shí)間了聪全,看了很多文檔和例程加上自己的實(shí)踐調(diào)試才有了這個(gè)工具類捶惜。一開始使用的是openSSL那一套加密工具實(shí)現(xiàn)的,但是覺得openSSL占用的空間略大荔烧,還是用Security.framework來實(shí)現(xiàn)的吱七。平時(shí)總是忙于業(yè)務(wù)需求的實(shí)現(xiàn),忽視了客戶端方面的安全鹤竭,網(wǎng)上對客戶端安全這一塊的資源也比較有限踊餐,但愿我這篇文章能對后來人有所幫助吧。

5.參考資料

看的資料比較多就不一一列舉了臀稚,主要還是通過Google吝岭、GitHubStackOverFlow吧寺、簡書窜管、知乎等平臺來獲取相關(guān)資源的。最后稚机,就在這里統(tǒng)一感謝一下相關(guān)資源的貢獻(xiàn)者吧幕帆。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市赖条,隨后出現(xiàn)的幾起案子失乾,更是在濱河造成了極大的恐慌,老刑警劉巖纬乍,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件碱茁,死亡現(xiàn)場離奇詭異,居然都是意外死亡仿贬,警方通過查閱死者的電腦和手機(jī)纽竣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蜓氨,“玉大人聋袋,你說我怎么就攤上這事∮镉” “怎么了舱馅?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵缰泡,是天一觀的道長刀荒。 經(jīng)常有香客問我,道長棘钞,這世上最難降的妖魔是什么缠借? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮宜猜,結(jié)果婚禮上泼返,老公的妹妹穿的比我還像新娘。我一直安慰自己姨拥,他們只是感情好绅喉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著叫乌,像睡著了一般柴罐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上憨奸,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天革屠,我揣著相機(jī)與錄音,去河邊找鬼排宰。 笑死似芝,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的板甘。 我是一名探鬼主播党瓮,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼盐类!你這毒婦竟也來了麻诀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤傲醉,失蹤者是張志新(化名)和其女友劉穎蝇闭,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體硬毕,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡呻引,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了吐咳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逻悠。...
    茶點(diǎn)故事閱讀 39,773評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡元践,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出童谒,到底是詐尸還是另有隱情单旁,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布饥伊,位于F島的核電站象浑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏琅豆。R本人自食惡果不足惜愉豺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望茫因。 院中可真熱鬧蚪拦,春花似錦、人聲如沸冻押。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽洛巢。三九已至括袒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間狼渊,已是汗流浹背箱熬。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留狈邑,地道東北人城须。 一個(gè)月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像米苹,于是被迫代替她去往敵國和親糕伐。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容