iOS应用安全-秘钥硬编码解决

安全-秘钥硬编码解决

发表于 2017-06-26 | 分类于 安全

导读 程序中经常用到需要用对称加密算法加解密,通常的做法是在代码中写死,硬编码到代码里。但是通过工具分析代码,是可以看到编码信息的,所以安全的做法是做一次变换,再硬编码进去。

秘钥硬编码是常见的安全问题。攻击者拿到编译后的包后,经过分析是可以拿到所有使用到的字符串的(可以使用ida),很容易泄露对称秘钥,导致安全问题。(非对称算法的公钥是可以公开的)

最安全的解决方案是:对称秘钥按照会话随机生成。通过非对称的(比如RSA)算法,两边交换秘钥。

不过大部分场景还是需要把秘钥写在程序中的,对称秘钥如何存储一直是安全的大难题,目前没有什么方案可以保证安全存储对称秘钥的方案,相关的方案只是增加了破解难度而已

相对安全的方案是:对秘钥进行变换。

使用的数学方法有:

  • 移位和循环移位   移位就是将一段数码按照规定的位数整体性地左移或右移。循环右移就是当右移时,把数码的最后的位移到数码的最前头,循环左移正相反。例如,对十进制数码12345678循环右移1位(十进制位)的结果为81234567,而循环左移1位的结果则为23456781。

  • 置换   就是将数码中的某一位的值根据置换表的规定,用另一位代替。它不像移位操作那样整齐有序,看上去杂乱无章。这正是加密所需,被经常应用。

  • 扩展   就是将一段数码扩展成比原来位数更长的数码。扩展方法有多种,例如,可以用置换的方法,以扩展置换表来规定扩展后的数码每一位的替代值。

  • 压缩   就是将一段数码压缩成比原来位数更短的数码。压缩方法有多种,例如,也可以用置换的方法,以表来规定压缩后的数码每一位的替代值。

  • 异或   这是一种二进制布尔代数运算。异或的数学符号为⊕ ,它的运算法则如下: 1⊕1 = 0 0⊕0 = 0 1⊕0 = 1 0⊕1 = 1   也可以简单地理解为,参与异或运算的两数位如相等,则结果为0,不等则为1。

  • 迭代   迭代就是多次重复相同的运算,这在密码算法中经常使用,以使得形成的密文更加难以破解。

通常是对秘钥进行变形,然后程序里面提供相关接口在运算过程中获取真实的秘钥。下面是几种常见的简单方案:

方案1:使用RSA加密保存

方案很简单,使用RSA的私钥进行加密,RSA的公钥写死在客户端里,使用的时候使用RSA进行一次解密操作。

优点: 简单容易实现,一般项目里都需要使用非对称的加密方法,利用公开的秘钥做一次解密。 缺点: 如果知道了算法很容易破解。

方案2:使用Base64进行编码,再保存

对秘钥进行Base64编码,然后再解码。

方案3:使用AES再次加密

再使用一次对称加密,两次不要使用相同的秘钥

方案4:自定义方案

下面给一个方案,对数据进行变形。算法如下:

  1. 对每一个字节做一次循环右移

  2. 对每一个字节用一个表的数据做位异或操作

  3. 转为16进制数

相关代码:

<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); //公式:循环左移n位: (x>>(N - n) ) | (x<<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); //公式:循环左移n位: (x>>(N - n) ) | (x<<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. 本地固定使用一段随机数16字节,使用上面的方法或自定义方法做一层变换后再存储。

  2. 启动后随机生成16字节的数据,持久化到本地(可以保存到keychain里)。后面如果有保存就直接使用。

  3. 两个做拼接后生成32字节作为对称秘钥。

好处:

  1. 秘钥是每个设备随机生成的,所以拿到固定秘钥和算法不会影响其他设备。

  2. 两段进行拼接加大了相关破解的难度

缺点:

  1. 首次读取持久化的秘钥有一定耗时

  2. 能破解一定能破解

最后

目前没有安全的方法保存秘钥,除非使用硬件来解决(后台的加密机使用的就是硬件,秘钥放在芯片里),所以本地保存数据需要遵循:

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

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

  3. 任何时候都不要保存密码

参考

  1. IDA使用

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容

  • 夜莺2517阅读 127,708评论 1 9
  • 版本:ios 1.2.1 亮点: 1.app角标可以实时更新天气温度或选择空气质量,建议处女座就不要选了,不然老想...
    我就是沉沉阅读 6,876评论 1 6
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,520评论 28 53
  • 兔子虽然是枚小硕 但学校的硕士四人寝不够 就被分到了博士楼里 两人一间 在学校的最西边 靠山 兔子的室友身体不好 ...
    待业的兔子阅读 2,583评论 2 9