iOS應(yīng)用安全-秘鑰硬編碼解決

安全-秘鑰硬編碼解決

發(fā)表于 2017-06-26 | 分類于 安全

導(dǎo)讀 程序中經(jīng)常用到需要用對稱加密算法加解密,通常的做法是在代碼中寫死,硬編碼到代碼里。但是通過工具分析代碼,是可以看到編碼信息的,所以安全的做法是做一次變換,再硬編碼進去。

秘鑰硬編碼是常見的安全問題。攻擊者拿到編譯后的包后,經(jīng)過分析是可以拿到所有使用到的字符串的(可以使用ida),很容易泄露對稱秘鑰,導(dǎo)致安全問題。(非對稱算法的公鑰是可以公開的)

最安全的解決方案是:對稱秘鑰按照會話隨機生成。通過非對稱的(比如RSA)算法,兩邊交換秘鑰。

不過大部分場景還是需要把秘鑰寫在程序中的,對稱秘鑰如何存儲一直是安全的大難題,目前沒有什么方案可以保證安全存儲對稱秘鑰的方案,相關(guān)的方案只是增加了破解難度而已

相對安全的方案是:對秘鑰進行變換。

使用的數(shù)學(xué)方法有:

  • 移位和循環(huán)移位   移位就是將一段數(shù)碼按照規(guī)定的位數(shù)整體性地左移或右移。循環(huán)右移就是當(dāng)右移時,把數(shù)碼的最后的位移到數(shù)碼的最前頭,循環(huán)左移正相反。例如,對十進制數(shù)碼12345678循環(huán)右移1位(十進制位)的結(jié)果為81234567,而循環(huán)左移1位的結(jié)果則為23456781。

  • 置換   就是將數(shù)碼中的某一位的值根據(jù)置換表的規(guī)定,用另一位代替。它不像移位操作那樣整齊有序,看上去雜亂無章。這正是加密所需,被經(jīng)常應(yīng)用。

  • 擴展   就是將一段數(shù)碼擴展成比原來位數(shù)更長的數(shù)碼。擴展方法有多種,例如,可以用置換的方法,以擴展置換表來規(guī)定擴展后的數(shù)碼每一位的替代值。

  • 壓縮   就是將一段數(shù)碼壓縮成比原來位數(shù)更短的數(shù)碼。壓縮方法有多種,例如,也可以用置換的方法,以表來規(guī)定壓縮后的數(shù)碼每一位的替代值。

  • 異或   這是一種二進制布爾代數(shù)運算。異或的數(shù)學(xué)符號為⊕ ,它的運算法則如下: 1⊕1 = 0 0⊕0 = 0 1⊕0 = 1 0⊕1 = 1   也可以簡單地理解為,參與異或運算的兩數(shù)位如相等,則結(jié)果為0,不等則為1。

  • 迭代   迭代就是多次重復(fù)相同的運算,這在密碼算法中經(jīng)常使用,以使得形成的密文更加難以破解。

通常是對秘鑰進行變形,然后程序里面提供相關(guān)接口在運算過程中獲取真實的秘鑰。下面是幾種常見的簡單方案:

方案1:使用RSA加密保存

方案很簡單,使用RSA的私鑰進行加密,RSA的公鑰寫死在客戶端里,使用的時候使用RSA進行一次解密操作。

優(yōu)點: 簡單容易實現(xiàn),一般項目里都需要使用非對稱的加密方法,利用公開的秘鑰做一次解密。 缺點: 如果知道了算法很容易破解。

方案2:使用Base64進行編碼,再保存

對秘鑰進行Base64編碼,然后再解碼。

方案3:使用AES再次加密

再使用一次對稱加密,兩次不要使用相同的秘鑰

方案4:自定義方案

下面給一個方案,對數(shù)據(jù)進行變形。算法如下:

  1. 對每一個字節(jié)做一次循環(huán)右移

  2. 對每一個字節(jié)用一個表的數(shù)據(jù)做位異或操作

  3. 轉(zhuǎn)為16進制數(shù)

相關(guān)代碼:

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n44" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; background-position: initial initial; background-repeat: initial initial;">//
// Utils.m
// Safe
//
// Created by bolei on 2017/7/18.
// Copyright ? 2017年 bolei. All rights reserved.
//

import "Utils.h"

import "NSData+HexString.h"

//使用自己的映射表
char changeMap[16] = {'w','o','s','h','i','b','o','l','e','i','s','h','a','i','g','e'};

@implementation Utils

  • (NSString *)hardKeyEncode:(NSString *)key {
    if ([key length] == 0) {
    return @"";
    }
    NSData *data = [key dataUsingEncoding:NSUTF8StringEncoding];

NSUInteger i, len;
unsigned char *bytes;

len = data.length;
bytes = (unsigned char*)data.bytes;

for (i = 0; i < len; i++) {
NSUInteger index = i % 16;
unsigned char p = bytes[i];
p = (p << 7 || p >> 1); //公式:循環(huán)左移n位: (x>>(N - n) ) | (x<<n);循環(huán)右移n位: (x<<(N - n) ) | (x>>n)。
p ^= changeMap[index];
}

NSData *changeData = [NSData dataWithBytes:bytes length:len];
NSString *keyHex = [data hexStringFromData:changeData];

return keyHex;
}

  • (NSString *)hardKeyDecode:(NSString *)key {
    if ([key length] == 0) {
    return @"";
    }

NSData *data = [NSData dataFromHexString:key];

if ([data length] == 0) {
return @"";
}

NSUInteger i, len;
unsigned char *bytes;

len = data.length;
bytes = (unsigned char*)data.bytes;

for (i = 0; i < len; i++) {
NSUInteger index = i % 16;
unsigned char p = bytes[i];
p = (p >> 7 || p << 1); //公式:循環(huán)左移n位: (x>>(N - n) ) | (x<<n);循環(huán)右移n位: (x<<(N - n) ) | (x>>n)。
p ^= changeMap[index];
}

NSData *changeData = [NSData dataWithBytes:bytes length:len];
NSString *result = [NSString stringWithUTF8String:changeData.bytes];
return result;
}

@end</pre>

推薦方案5: 隨機+固定

  1. 本地固定使用一段隨機數(shù)16字節(jié),使用上面的方法或自定義方法做一層變換后再存儲。

  2. 啟動后隨機生成16字節(jié)的數(shù)據(jù),持久化到本地(可以保存到keychain里)。后面如果有保存就直接使用。

  3. 兩個做拼接后生成32字節(jié)作為對稱秘鑰。

好處:

  1. 秘鑰是每個設(shè)備隨機生成的,所以拿到固定秘鑰和算法不會影響其他設(shè)備。

  2. 兩段進行拼接加大了相關(guān)破解的難度

缺點:

  1. 首次讀取持久化的秘鑰有一定耗時

  2. 能破解一定能破解

最后

目前沒有安全的方法保存秘鑰,除非使用硬件來解決(后臺的加密機使用的就是硬件,秘鑰放在芯片里),所以本地保存數(shù)據(jù)需要遵循:

  1. 需要長久更安全的保存,使用keychain的方式保存

  2. 不要保存敏感信息,如果要保存需要先做脫敏

  3. 任何時候都不要保存密碼

參考

  1. IDA使用

  2. IOS安全– 字符串加密那點小事

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,990評論 2 374

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