0

PayPal API for iOS を統合する iPhone アプリケーションを作成しています。API は、リクエストを送信するときに API クレデンシャルを必要とします。PayPal API を読んだところ、

モバイル アプリケーションから直接 PayPal にエクスプレス チェックアウト要求を送信しないでください。リクエストには、PayPal API 資格情報が必要です。認証情報をモバイル デバイスに配置すると、お客様と PayPal が容認できないセキュリティ リスクにさらされます。安全なサーバーからのみエクスプレス チェックアウト リクエストを送信します。

私の質問は、資格情報が公開またはハッキングされる可能性を減らすために、API 資格情報を保存する最良の方法は何ですか? 認証情報を iPhone ビルドに添付するのは危険ですか? なぜ、またはどのように?これらの資格情報を安全なサーバーに保存することは十分に信頼できますか?

編集:iOSのキーチェーンアクセスAPIはどのように私を助けることができますか?

4

2 に答える 2

3

アプリに API キーを配置することは、完全に安全ではありません。アプリをダウンロードしたり、アプリがインストールされたスマートフォンを手に入れたりすることができる人なら誰でも、さまざまなテクニックを使って API キーを簡単に読み取ることができます。これは、@MatthiasBauch が提案したことを実行し、後でシークレットをダウンロードした場合でも当てはまります。@Rexeisenが提案したことを実行して文字列を難読化しても、それは保持されます。

支払いを処理するために、Apple のビルトイン サブスクリプション サービスを使用するのが最善の策です (これは適用されない可能性があり、料金はかかりますが、電話でできることよりも安全である可能性があります)。

あなたがそれをしたくない、またはできない場合でも、アプリの各インスタンスに、あなたが制御するサーバーでダウンロードするときに登録する一意の ID を与えます。そのサーバーは、paypal の資格情報を持っており、代わりに API 呼び出しを行います。このようにして、特定の電話が盗まれたり、サーバーへのAPIキーが読み取られたりした場合、そのキーを取り消すだけで、paypal APIキーは引き続き安全です. 重要な警告: アプリのキーを実際に取り消すまでは、それを持っている人は誰でもそれを使用して、サーバーがサポートする呼び出しを行うことができます。これは非常に悪いことかもしれません。

于 2012-05-22T16:25:15.460 に答える
1

ほぼすべてのアプリで文字列ユーティリティを実行して(試してみると、ちょっと怖いです)、コードから文字列を取得できるため、危険です。通常、シークレットをアプリにパッケージ化することをお勧めしますが、他の場所の安全なサーバーに残しておきます。アプリに配置する必要がある場合、できることの1つは、文字列を難読化して明確にしないことです。

NSString *secret = kTwitterClientSecret;
NSData *secretData = [secret dataUsingEncoding:NSUTF8StringEncoding];
NSString *key = @"Twitter";
[secretData obfuscateOrDeobfuscateWithKey:key];
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *path = [NSString stringWithFormat:@"%@/%@-%@", documentsPath, key, @"output"];
[secretData writeToFile:path atomically:NO];
NSLog(@"Wrote obfuscated data to: %@", documentsPath);

obfuscateOrDeobfuscateWithKeyがNSDataのカテゴリである場合

// Inspiration from: http://iosdevelopertips.com/cocoa/obfuscation-encryption-of-string-nsstring.html
- (void)obfuscateOrDeobfuscateWithKey:(NSString *)key
{
    // Get pointer to data to obfuscate
    char *dataPtr = (char *) [self bytes];

    // Get pointer to key data
    char *keyData = (char *) [[key dataUsingEncoding:NSUTF8StringEncoding] bytes];

    // Points to each char in sequence in the key
    char *keyPtr = keyData;
    int keyIndex = 0;

    // For each character in data, xor with current value in key
    for (int x = 0; x < [self length]; x++) {
        // Replace current character in data with current character xor'd with current key value.
        // Bump each pointer to the next character.
        *dataPtr = *dataPtr ^ *keyPtr;
        dataPtr++;
        keyPtr++;

        // If at end of key data, reset count and set key pointer back to start of key value
        if (++keyIndex == [key length]) {
            keyIndex = 0, keyPtr = keyData;
        }
    }
}

次に、定数を次のように宣言できます

static unsigned char const kTwitterClientSecret[] = {
    0x00, 0x00, 0x00, ... etc ... 
};
static unsigned int const kTwitterClientSecret_len = LENGTH;

次に、文字列を元に戻すには、次のことができます

[NSString deobfuscatedStringWithBytes:kTwitterClientSecret length:kTwitterClientSecret_len key:@"Twitter"];

これはNSStringのカテゴリです

+ (NSString *)deobfuscatedStringWithBytes:(const void *)bytes length:(NSUInteger)length key:(NSString *)key
{
    NSData *deobfuscatedData = [NSData dataWithBytes:bytes length:length];
    [deobfuscatedData obfuscateOrDeobfuscateWithKey:key];
    return [[NSString alloc] initWithData:deobfuscatedData encoding:NSUTF8StringEncoding];
}

これは非常に単純な難読化を行い、文字列には表示されません。

于 2012-05-22T15:36:46.500 に答える