談?wù)刬OS加密:AES+RSA

最近在項(xiàng)目中需要對(duì)用戶信息及數(shù)據(jù)傳輸進(jìn)行加密验烧,網(wǎng)上搜索了下相關(guān)信息向叉,最后決定采用AES+RSA的方式。
AES:對(duì)稱加密眼五,加密與解密使用的是同樣的密鑰妆艘,所以速度快,但由于需要將密鑰在網(wǎng)絡(luò)傳輸看幼,所以安全性不高批旺。
RSA:非對(duì)稱加密,使用了一對(duì)密鑰诵姜,公鑰與私鑰汽煮,所以安全性高,但加密與解密速度慢棚唆。
所以我們結(jié)合兩者的特性暇赤,采用AES對(duì)傳輸?shù)臄?shù)據(jù)進(jìn)行加密,然后采用RSA對(duì)AES的秘鑰進(jìn)行加密宵凌。AES的秘鑰是客戶端生成的(iOS我采用的是UUID)鞋囊,然后把AES的秘鑰用不可逆的RSA加密,最后發(fā)送給服務(wù)器的是RSA加密過的AES的秘鑰和AES加密的數(shù)據(jù)(是不是有點(diǎn)暈~)瞎惫。服務(wù)器端保留RSA的私鑰溜腐,可以對(duì)AES的秘鑰進(jìn)行解密,然后用AES的秘鑰解密數(shù)據(jù)瓜喇。這樣就拿到客戶端的數(shù)據(jù)了挺益。服務(wù)器進(jìn)行數(shù)據(jù)處理過后,用傳過來(lái)的AES的秘鑰加密數(shù)據(jù)再傳給客戶端乘寒。
說(shuō)的比較籠統(tǒng)望众,具體的邏輯可以參考以下鏈接:http://www.reibang.com/p/ec7bb7325ff2

關(guān)于AES的集成,網(wǎng)上也是眾說(shuō)紛紜伞辛,以下是我的實(shí)現(xiàn)方式:

//MARK:AES加密
func aesEncrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
        if let keyData = key.data(using: String.Encoding.utf8),
            let data = self.data(using: String.Encoding.utf8),
            let cryptData    = NSMutableData(length: Int((data.count)) + kCCBlockSizeAES128) {


            let keyLength              = size_t(kCCKeySizeAES128)
            let operation: CCOperation = UInt32(kCCEncrypt)
            let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
            let options:   CCOptions   = UInt32(options)



            var numBytesEncrypted :size_t = 0

            let cryptStatus = CCCrypt(operation,
                                      algoritm,
                                      options,
                                      (keyData as NSData).bytes, keyLength,
                                      iv,
                                      (data as NSData).bytes, data.count,
                                      cryptData.mutableBytes, cryptData.length,
                                      &numBytesEncrypted)

            if UInt32(cryptStatus) == UInt32(kCCSuccess) {
                cryptData.length = Int(numBytesEncrypted)
                let base64cryptString = cryptData.base64EncodedString(options: .lineLength64Characters)
                return base64cryptString


            }
            else {
                return nil
            }
        }
        return nil
    }

    //MARK:AES解密
    func aesDecrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
        if let keyData = key.data(using: String.Encoding.utf8),
            let data = NSData(base64Encoded: self, options: .ignoreUnknownCharacters),
            let cryptData    = NSMutableData(length: Int((data.length)) + kCCBlockSizeAES128) {

            let keyLength              = size_t(kCCKeySizeAES128)
            let operation: CCOperation = UInt32(kCCDecrypt)
            let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
            let options:   CCOptions   = UInt32(options)

            var numBytesEncrypted :size_t = 0

            let cryptStatus = CCCrypt(operation,
                                      algoritm,
                                      options,
                                      (keyData as NSData).bytes, keyLength,
                                      iv,
                                      data.bytes, data.length,
                                      cryptData.mutableBytes, cryptData.length,
                                      &numBytesEncrypted)

            if UInt32(cryptStatus) == UInt32(kCCSuccess) {
                cryptData.length = Int(numBytesEncrypted)
                let unencryptedMessage = String(data: cryptData as Data, encoding:String.Encoding.utf8)
                return unencryptedMessage
            }
            else {
                return nil
            }
        }
        return nil
    }

關(guān)于aes key烂翰、iv的意義:參見:http://www.reibang.com/p/df828a57cb8f
集成后,可以到https://blog.zhengxianjun.com/online-tool/crypto/aes/進(jìn)行驗(yàn)證蚤氏。

RSA的集成就更惡心了甘耿。關(guān)于RSA的公鑰、私鑰的生成瞧捌,有iOS自己生成和服務(wù)器端生成兩種方式(具體的解釋請(qǐng)自行Google~)棵里,我們采用的是服務(wù)器端生成润文。拿到服務(wù)器給的公鑰后,怎么用呢殿怜?典蝌?

有人說(shuō),用SecrecySwift(參見:http://swiftcn.io/topics/84)头谜,集成BBRSACryptor過程中發(fā)現(xiàn)openssl怎么都報(bào)錯(cuò)骏掀,感謝http://www.reibang.com/p/1e5f214ad789這篇博客詳細(xì)的解釋,但是最后集成到項(xiàng)目中還是報(bào)錯(cuò)柱告。于是又搜索了番截驮。發(fā)現(xiàn)https://github.com/ideawu/Objective-C-RSA這個(gè)共享庫(kù)(人民群眾的力量強(qiáng)大啊~~),最后簡(jiǎn)單的集成际度,測(cè)試(測(cè)試地址:https://blog.zhengxianjun.com/online-tool/rsa/)葵袭,通過,阿彌陀佛9粤狻坡锡!

至此,可以開森的進(jìn)行加密了窒所。

不是所有的數(shù)據(jù)傳輸都需要這么嚴(yán)格的加密的鹉勒。一般只是對(duì)用戶名的密碼、支付等相關(guān)信息才需要這么復(fù)雜的加密的吵取。對(duì)于普通請(qǐng)求禽额,我們采用的是MD5。

MD5也是不可逆的加密皮官。主要用于服務(wù)器上存儲(chǔ)用戶的密碼脯倒。 用戶Login的時(shí)候,系統(tǒng)是把用戶輸入的密碼計(jì)算成MD5值臣疑,然后再去和系統(tǒng)中保存的MD5值進(jìn)行比較盔憨,而系統(tǒng)并不“知道”用戶的密碼是什么徙菠。

我們知道讯沈,如果直接對(duì)密碼進(jìn)行散列,那么黑客可以對(duì)通過獲得這個(gè)密碼散列值婿奔,然后通過查散列值字典(例如MD5密碼破解網(wǎng)站)缺狠,得到某用戶的密碼。

加Salt可以一定程度上解決這一問題萍摊。所謂加Salt方法挤茄,就是加點(diǎn)“佐料”。其基本想法是這樣的:當(dāng)用戶首次提供密碼時(shí)(通常是注冊(cè)時(shí))冰木,由系統(tǒng)自動(dòng)往這個(gè)密碼里撒一些“佐料”穷劈,然后再散列笼恰。而當(dāng)用戶登錄時(shí),系統(tǒng)為用戶提供的代碼撒上同樣的“佐料”歇终,然后散列社证,再比較散列值,已確定密碼是否正確评凝。

這里的“佐料”被稱作“Salt值”追葡,這個(gè)值是由系統(tǒng)隨機(jī)生成的,并且只有系統(tǒng)知道奕短。這樣宜肉,即便兩個(gè)用戶使用了同一個(gè)密碼,由于系統(tǒng)為它們生成的salt值不同翎碑,他們的散列值也是不同的谬返。即便黑客可以通過自己的密碼和自己生成的散列值來(lái)找具有特定密碼的用戶,但這個(gè)幾率太小了(密碼和salt值都得和黑客使用的一樣才行)日杈。

補(bǔ)充一點(diǎn):客戶端在向服務(wù)端接口進(jìn)行請(qǐng)求朱浴,如果請(qǐng)求信息進(jìn)行了加密處理,被第三方截取到請(qǐng)求包达椰,雖然第三方無(wú)法解密獲取其中的數(shù)據(jù)翰蠢,但是可以使用該請(qǐng)求包進(jìn)行重復(fù)的請(qǐng)求操作。如果服務(wù)端不進(jìn)行防重放攻擊啰劲,就會(huì)參數(shù)服務(wù)器壓力增大梁沧,數(shù)據(jù)紊亂的后果。而使用添加時(shí)間戳的方式可以解決這一問題蝇裤。在請(qǐng)求中廷支,除了時(shí)間戳,再添加一個(gè)nonce參數(shù)栓辜,這樣時(shí)間戳允許十五分鐘偏差恋拍,那么服務(wù)器只要記錄十五分鐘以內(nèi)的nonce參數(shù)就行了,這樣可以避免重放攻擊藕甩。

賦下MD5的加密方法施敢。

//MARK:MD5 加密方式 不可逆
    var MD5: String! {
        let str = self.cString(using: String.Encoding.utf8)
        let strLen = CC_LONG(self.lengthOfBytes(using: String.Encoding.utf8))
        let digestLen = Int(CC_MD5_DIGEST_LENGTH)
        let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)

        CC_MD5(str!, strLen, result)

        let hash = NSMutableString()
        for i in 0..<digestLen {
            hash.appendFormat("%02x", result[i])
        }

        result.deallocate(capacity: digestLen)

        return hash as String
    }

本人QQ:297959735 郵箱:zgsddzwj@163.com,歡迎提意見狭莱。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末僵娃,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子腋妙,更是在濱河造成了極大的恐慌默怨,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件骤素,死亡現(xiàn)場(chǎng)離奇詭異匙睹,居然都是意外死亡愚屁,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門痕檬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)集绰,“玉大人,你說(shuō)我怎么就攤上這事谆棺≡匝啵” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵改淑,是天一觀的道長(zhǎng)碍岔。 經(jīng)常有香客問我,道長(zhǎng)朵夏,這世上最難降的妖魔是什么蔼啦? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮仰猖,結(jié)果婚禮上捏肢,老公的妹妹穿的比我還像新娘。我一直安慰自己饥侵,他們只是感情好鸵赫,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著躏升,像睡著了一般辩棒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上膨疏,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天一睁,我揣著相機(jī)與錄音,去河邊找鬼佃却。 笑死者吁,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的饲帅。 我是一名探鬼主播复凳,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼洒闸!你這毒婦竟也來(lái)了染坯?” 一聲冷哼從身側(cè)響起均芽,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤丘逸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后掀宋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體深纲,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仲锄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了湃鹊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片儒喊。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖币呵,靈堂內(nèi)的尸體忽然破棺而出怀愧,到底是詐尸還是另有隱情,我是刑警寧澤余赢,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布芯义,位于F島的核電站,受9級(jí)特大地震影響妻柒,放射性物質(zhì)發(fā)生泄漏扛拨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一举塔、第九天 我趴在偏房一處隱蔽的房頂上張望绑警。 院中可真熱鬧,春花似錦央渣、人聲如沸计盒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)章郁。三九已至,卻和暖如春志衍,著一層夾襖步出監(jiān)牢的瞬間暖庄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留眶拉,地道東北人琅坡。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像肩钠,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子暂殖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

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