如何避免硬编码加密密钥(目标C)?

ThE*_*FuL 3 security encryption sha1 objective-c ios

在我的Objective C代码中,我的代码中有一个消费者密钥和密码,用于SHA-1加密.我想知道的是我是否可以避免硬编码来提高安全性.到目前为止我找到了以下内容,

查找1 https://www.owasp.org/index.php/Technical_Risks_of_Reverse_Engineering_and_Unauthorized_Code_Modification#Cryptographic_Key_Replacement 步骤说明如下,

  1. 损坏在源代码中声明的静态键.在磁盘上应该损坏这些密钥,以防止对手分析和拦截原始密钥;

  2. 接下来,应用程序应该在需要密钥的代码使用它之前修复密钥;

  3. 在使用密钥之前,应用程序应立即执行密钥值的校验和,以验证未损坏的密钥是否与代码在构建时声明的值相匹配; 和

  4. 最后,应用程序在应用程序完成对特定调用的使用后,应立即重新损坏内存中的密钥.

寻找2 https://github.com/UrbanApps/UAObfuscatedString

有人可以帮帮我吗?

示例代码:

+ (NSString *) getOauthHeaderForRequestString:(NSString *)requestString {

NSString *oauthConsumerKey = @"<consumer key which I want avoid hardcoding>";
NSString *oauthConsumerSecret = @"<consumer secret which I want to avoid hardcoding>";
NSString *oauthSignatureMethod = @"HMAC-SHA1";
NSString *oauthVersion = @"1.0";

NSString *oauthNonce = [self generateNonce];
NSString *oauthtimestamp = [NSString stringWithFormat:@"%d", (int)[[NSDate date] timeIntervalSince1970]];

NSArray * params = [NSArray arrayWithObjects:
                    [NSString stringWithFormat:@"%@%%3D%@", @"oauth_consumer_key", oauthConsumerKey],
                    [NSString stringWithFormat:@"%@%%3D%@", @"oauth_nonce", oauthNonce],
                    [NSString stringWithFormat:@"%@%%3D%@", @"oauth_signature_method", oauthSignatureMethod],
                    [NSString stringWithFormat:@"%@%%3D%@", @"oauth_timestamp", oauthtimestamp],
                    [NSString stringWithFormat:@"%@%%3D%@", @"oauth_version", oauthVersion],
                    [NSString stringWithFormat:@"%@%%3D%@", @"request", [requestString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]],
                    nil];

params = [params sortedArrayUsingSelector:@selector(compare:)];
NSString *parameters = [params componentsJoinedByString:@"%26"];

NSString *postURL = @"<my post url>";

NSArray * baseComponents = [NSArray arrayWithObjects:
                            @"POST",
                            [self encodeString:postURL],
                            parameters,
                            nil];
NSString * baseString = [baseComponents componentsJoinedByString:@"&"];

NSArray *signingKeyComponents = [NSArray arrayWithObjects:oauthConsumerSecret, @"", nil];
NSString *signingKey = [signingKeyComponents componentsJoinedByString:@"&"];

NSData *signingKeyData = [signingKey dataUsingEncoding:NSUTF8StringEncoding];
NSData *baseData = [baseString dataUsingEncoding:NSUTF8StringEncoding];

uint8_t digest[20] = {0};
CCHmac(kCCHmacAlgSHA1, signingKeyData.bytes, signingKeyData.length, baseData.bytes, baseData.length, digest);

NSData *signatureData = [NSData dataWithBytes:digest length:20];

NSString *oauthSignature = [self base64forData:signatureData];

// final request build
NSString *oauthHeader = @"OAuth ";
oauthHeader = [oauthHeader stringByAppendingFormat:@"oauth_consumer_key=\"%@\"",oauthConsumerKey];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_nonce=\"%@\"",oauthNonce];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_signature=\"%@\"",[self encodeString:oauthSignature]];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_signature_method=\"%@\"",oauthSignatureMethod];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_timestamp=\"%@\"",oauthtimestamp];
oauthHeader = [oauthHeader stringByAppendingFormat:@",oauth_version=\"1.0\""];

return oauthHeader;
}
Run Code Online (Sandbox Code Playgroud)

Rob*_*ier 10

我之前已经写过关于解决这个问题的挑战,但是我想用你的UAObfuscatedString想法来展示一点,因为我认为这是大多数人都在寻找的解决方案,但是比什么都没有.值得注意的是:我不是特别擅长这一点.我不是一个经验丰富的逆向工程师,商业系统超出了我的技能.我只是一个有Hopper的人和五分钟的逆向工程工作(我跑了一个计时器; 5:35s,包括升级Hopper,因为我几个月没有运行它).

所以,我写了一个iOS程序UAObfuscatedString.我使用Swift是因为Swift通常比ObjC更难逆向工程.ObjC是逆向工程师的梦想.

let identifier = "c".o.m.dot.u.r.b.a.n.a.p.p.s.dot.e.x.a.m.p.l.e

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    print(identifier)
    return true
}
Run Code Online (Sandbox Code Playgroud)

然后我将它存档,所以它是优化的代码等,就像你发送到App Store一样.然后我将它加载到Hopper并查看应用程序代表init.这是常量初始化的地方,基于大多数人将这些东西粘贴在他们的app委托中的假设.显然,如果我看到一个名为KeyStorageor 的类SecretStuffHelper,我会先看一下......

void * -[_TtC13ObfuscateTest11AppDelegate init](void * self, void * _cmd) {
    *(r31 + 0xffffffffffffffe0) = r20;
    *(0xfffffffffffffff0 + r31) = r19;
    *(r31 + 0xfffffffffffffff0) = r29;
    *(r31 + 0x0) = r30;
    r0 = sub_100005e14();
    return r0;
}
Run Code Online (Sandbox Code Playgroud)

嗯,它称之为匿名函数sub_100005e14().让我们看看它的作用.

...
0000000100005e38         adr        x0, #0x100006859                            ; "c"
...
0000000100005e48         bl         imp___stubs___T0SS18UAObfuscatedStringE1oSSfg
...
0000000100005e50         bl         imp___stubs___T0SS18UAObfuscatedStringE1mSSfg
...
0000000100005e74         bl         imp___stubs___T0SS18UAObfuscatedStringE3dotSSfg
...
0000000100005e98         bl         imp___stubs___T0SS18UAObfuscatedStringE1uSSfg
...
0000000100005ebc         bl         imp___stubs___T0SS18UAObfuscatedStringE1rSSfg
...
0000000100005ee0         bl         imp___stubs___T0SS18UAObfuscatedStringE1bSSfg
...
0000000100005f04         bl         imp___stubs___T0SS18UAObfuscatedStringE1aSSfg
...
0000000100005f28         bl         imp___stubs___T0SS18UAObfuscatedStringE1nSSfg
...
0000000100005f4c         bl         imp___stubs___T0SS18UAObfuscatedStringE1aSSfg
...
0000000100005f70         bl         imp___stubs___T0SS18UAObfuscatedStringE1pSSfg
...
0000000100005f94         bl         imp___stubs___T0SS18UAObfuscatedStringE1pSSfg
...
0000000100005fb8         bl         imp___stubs___T0SS18UAObfuscatedStringE1sSSfg
...
0000000100005fdc         bl         imp___stubs___T0SS18UAObfuscatedStringE3dotSSfg
...
0000000100006000         bl         imp___stubs___T0SS18UAObfuscatedStringE1eSSfg
...
0000000100006024         bl         imp___stubs___T0SS18UAObfuscatedStringE1xSSfg
...
0000000100006048         bl         imp___stubs___T0SS18UAObfuscatedStringE1aSSfg
...
000000010000606c         bl         imp___stubs___T0SS18UAObfuscatedStringE1mSSfg
...
0000000100006090         bl         imp___stubs___T0SS18UAObfuscatedStringE1pSSfg
...
00000001000060b4         bl         imp___stubs___T0SS18UAObfuscatedStringE1lSSfg
...
00000001000060d8          bl         imp___stubs___T0SS18UAObfuscatedStringE1eSSfg
Run Code Online (Sandbox Code Playgroud)

我不确定为什么Swift demangler不能在这里工作,但无论如何,我们可以很容易地看到这种模式:

_T0SS18UAObfuscatedStringE1oSSfg => o
_T0SS18UAObfuscatedStringE1mSSfg => m
_T0SS18UAObfuscatedStringE3dotSSfg => dot => .
_T0SS18UAObfuscatedStringE1uSSfg => u
...
Run Code Online (Sandbox Code Playgroud)

意识到有这些USObfuscatedString方法,我搜索并在应用程序中找到使用混淆字符串的所有方法.如果我愿意花一点时间玩我的游戏并花一天时间玩它,我可能会写一个工具来自动提取每一个UAObfuscatedString只是使用otool和二进制.

这是深刻的教训.您刚刚标记了要隐藏的所有字符串.一旦我意识到这UAObfuscatedString是一件事,你就让我更容易找到你的敏感信息.它实际上比什么都没有.你唯一的希望是攻击者不知道这存在.这就是混淆的问题,以及混淆与安全的区别.

我还要强调,我花了5分35秒攻击这个程序.是的,我基本上知道我在寻找什么样的东西,但我也没有这方面的技能.如果UAObfuscatedString要变得流行,我向你保证,自动检测/去混淆工具将成为每个脚本 - 小子的工具箱的一部分("script-kiddie"是安全人员称之为不知道他们在做什么的攻击者,并且只使用其他人编写的自动化工具.

这里的教训是,如果你想混淆,你最好自己制定一些随机的方法.它不会有效,但它可能不会像大多数FOSS解决方案那样对你的目标产生积极的伤害."免费和开源"对安全性非常有利,但对于默默无闻而言是最糟糕的事情.

如果隐藏信息对您的业务计划非常重要并且您无法更改您的业务计划,那么您应该花费大量资金解决此问题,并雇用一个致力于不断改进您的混淆系统的人员队伍,以保持领先攻击者将适应你建立的任何东西.

  • @virumax Swift具有广泛的静态分派功能,可以内联函数,然后根据这些功能执行优化.这使得生成的Swift与原始代码的关联性远远低于Objective-C,后者无法跨消息传递进行优化(objc_msgSend).整个编译后的objc_msgSend调用Objc必然会告诉你方法的名称.这在优化的Swift代码中通常不可用.虽然Swift*可以*使用ObjC运行时,但它没有,而且很多Swift都没有.在这方面,Swift更接近C++. (3认同)