Swift 字符串混淆器

您是否将 API 密钥等或多或少敏感的字符串直接存储在应用程序代码中?例如像这样

String stored in app

您是否知道任何人都可以相对容易地反汇编应用程序并获取这些字符串?

decompiled_string

此实用程序将使用注释 //:obfuscate 注释的字符串转换为字节数组,并使它们在反汇编代码中更难找到。这不是一个万无一失的解决方案,但总比一开始就让它们可读要好。

string_obfuscated

安装

克隆仓库并运行 make install

用法

  1. 安装 swift_string_obfuscator 实用程序

  2. 使用注释 \\:obfuscate 注释敏感字符串

  3. 创建一个新的“运行脚本阶段”,并为包含敏感字符串的文件运行 swift_string_obfuscator。源文件和目标文件可以是同一个。

    另一种可能的解决方案是使用两个文件。一个文件包含明文字符串,并从构建中排除;第二个文件包含混淆后的字符串,并包含在构建中。

    swift_string_obfuscator -s ${PROJECT_DIR}/SampleApp/API.swift -t ${PROJECT_DIR}/SampleApp/API.swift
    

示例

包含明文字符串的输入。

    //:obfuscate
    let apiKey = "something-secret"

    //:obfuscate
    let apiKey2="something-secret-without-spaces"

    //:obfuscate
    //useless line, only for test purposes

    let nonObfuscated: String = "non-obfuscated-string"

    struct XStruct {
        let x: Int
        
        //:obfuscate
        let apiKey3 = "key-in-struct"
        
        //:obfuscate
        var param: String {
            return "key-in-computed-property"
        }
        
        //:obfuscate
        var dynamic2: String { "key-in-computed-property-2" }
    }

    class Y {
        //:obfuscate
        static let keyInClass: String = "api-key-in-class"

        func apiFuncParam(_ key: String) { return }
    }

    func test() {
        let testClass = Y()
        //:obfuscate
        testClass.apiFuncParam("api_key_func_param")
    }

混淆后的输出

    //:obfuscate
    let apiKey = String(bytes: [115,111,109,101,116,104,105,110,103,45,115,101,99,114,101,116], encoding: .utf8)

    //:obfuscate
    let apiKey2=String(bytes: [115,111,109,101,116,104,105,110,103,45,115,101,99,114,101,116,45,119,105,116,104,111,117,116,45,115,112,97,99,101,115], encoding: .utf8)

    //:obfuscate
    //useless line, only for test purposes

    let nonObfuscated: String = "non-obfuscated-string"

    struct XStruct {
        let x: Int
        
        //:obfuscate
        let apiKey3 = String(bytes: [107,101,121,45,105,110,45,115,116,114,117,99,116], encoding: .utf8)
        
        //:obfuscate
        var param: String {
            return String(bytes: [107,101,121,45,105,110,45,99,111,109,112,117,116,101,100,45,112,114,111,112,101,114,116,121], encoding: .utf8)
        }
        
        //:obfuscate
        var dynamic2: String { String(bytes: [107,101,121,45,105,110,45,99,111,109,112,117,116,101,100,45,112,114,111,112,101,114,116,121,45,50], encoding: .utf8)}
    }

    class Y {
        //:obfuscate
        static let keyInClass: String = String(bytes: [97,112,105,45,107,101,121,45,105,110,45,99,108,97,115,115], encoding: .utf8)

        func apiFuncParam(_ key: String) { return }
    }

    func test() {
        let testClass = Y()
        //:obfuscate
        testClass.apiFuncParam(String(bytes: [97,112,105,95,107,101,121,95,102,117,110,99,95,112,97,114,97,109], encoding: .utf8))
    }