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

2024-04-24

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

发现1 https://www.owasp.org/index.php/Technical_Risks_of_Reverse_Engineering_and_Unauthorized_Code_Modification#Cryptographic_Key_Replacement 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 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;
}

我写过关于之前解决这个问题的挑战 https://stackoverflow.com/questions/9401315/ios-5-how-to-encrypt-property-list-in-the-bundle,但我想用你的来演示一下UAObfuscatedString想法,因为我认为这是大多数人正在寻找的解决方案,但比没有更糟糕。需要注意的是:我并不是特别擅长这一点。我不是一位经验丰富的逆向工程师,商业系统远远超出了我的技能范围。我只是一个有Hopper https://www.hopperapp.com以及实际上五分钟的逆向工程工作(我运行了一个计时器;5:35 秒,包括升级 Hopper,因为我已经几个月没有运行它了)。

所以,我写了一个iOS程序UAObfuscatedString。我使用 Swift 是因为 Swift 通常比 ObjC 更难进行逆向工程。ObjC 是逆向工程师的梦想。 http://robnapier.net/obfuscating-cocoa

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
}

然后我将其存档,因此它是优化的代码等,就像您发送到应用程序商店一样。然后我将其加载到 Hopper 中并查看应用程序委托的init。这就是常量初始化的地方,基于大多数人将这些东西放在他们的应用程序委托中的假设。显然,如果我看到一个名为KeyStorage or 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;
}

嗯,它调用这个匿名函数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

我不确定为什么 Swift demangler 在这里不起作用,但无论如何,我们可以轻松地看到该模式:

_T0SS18UAObfuscatedStringE1oSSfg => o
_T0SS18UAObfuscatedStringE1mSSfg => m
_T0SS18UAObfuscatedStringE3dotSSfg => dot => .
_T0SS18UAObfuscatedStringE1uSSfg => u
...

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

这就是深刻的教训。您刚刚标记了所有要隐藏的字符串。一旦我意识到UAObfuscatedString是一件事,你刚刚做到了easier以便我找到您的敏感信息。从字面上看,这比没有更糟糕。您唯一的希望是攻击者不知道它的存在。这就是混淆的问题,也是混淆与安全的区别。

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

这里的教训是,如果你想混淆,你最好自己编一些随机的方法。它不会有效,但它可能不会像大多数自由和开源软件解决方案那样对您的目标产生积极的损害。 “免费和开源”对于安全来说可能非常有好处,但对于默默无闻来说却是最糟糕的事情。

如果隐藏信息对您的业务计划确实很重要,并且您无法更改您的业务计划,那么您应该期望在这个问题上花费大量资金,并聘请一个致力于不断发展您的混淆系统的团队,以保持领先地位。攻击者会适应您构建的任何内容。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何避免硬编码密钥进行加密(目标 C)? 的相关文章

随机推荐