web-dev-qa-db-ja.com

Androidでのbase64エンコード公開鍵の強力な暗号化

Androidアプリケーションに存在する公開鍵を強力に暗号化する方法を知りたい。

それはAndroidの アドバイス です

公開鍵を悪意のあるユーザーやハッカーから保護するために、公開鍵をリテラル文字列全体として埋め込まないでください。代わりに、実行時に文字列を断片から構築するか、ビット操作(たとえば、XORと他の文字列を使用)を使用して実際のキーを非表示にします。キー自体は秘密情報ではありませんが、ハッカーや悪意のあるユーザーが公開鍵を別の鍵に簡単に置き換えられるようにしたい。

部分文字列や暗号化などの特定の解決策がありますが、効率的な方法でそれを実現する方法を知りたいです。

13
Adithya

まず、必要なのは暗号化ではないことに注意してください。このアドバイスは公開鍵に関するものです。公開鍵は、その名前が示すように、秘密ではありません(プライバシーを保護する場合を除きます。ただし、アプリケーションの鍵がアプリケーション内にある場合、プライバシーは関係しません)。必要なのは、公開キーのintegrityを確認することです。つまり、悪意のあるエンティティがそれを別のキーで置き換えることができないようにします。

アプリケーションは、公開鍵を使用して注文書を認証します。購入のイベントの通常のシーケンスは次のとおりです。

  1. ユーザーはGoogleサーバーに接続し、アプリ内機能を購入するためにいくらかお金を支払います。
  2. Googleサーバーがその購入の領収書を発行します。サーバーを離れることのない秘密鍵でこのレシートに署名します。
  3. モバイルデバイスで実行されているアプリケーションがレシートをダウンロードします。
  4. アプリケーションは、アプリケーションにバンドルされている公開鍵に基づいて、レシートが本物であることを確認します。
  5. 購入が繰り返し可能なものである場合(たとえば、機能のロックを解除するのではなく、X分間の保護されたコンテンツをダウンロードできるようにする場合)、アプリケーションは、同じ領収書を2回使用できないようにする必要があります(リプレイ攻撃)。これは、購入を「消費」することによって行われます。

問題は、ユーザーがアプリケーションのコードまたはデータを変更して、本物の鍵ではなく自分が選択した公開鍵を配置できることです。特に、彼は秘密鍵を知っている公開鍵を置くかもしれません。これを行うと、サーバーを経由せずに購入領収書を生成でき、アプリケーションはステップ4でそれらを本物として受け入れます。

この攻撃から保護するために必要なことは、公開鍵を変更する試みを検出することです。攻撃者が公開鍵を変更できない限り、攻撃者が公開鍵を読み取ることができるかどうかは問題ではありません。つまり、アプリケーションには、キーが本物であることを確認するコードが含まれている必要があります。しかし、あなたが何をするにせよ、攻撃者は検証コードを変更する可能性があります(if is_genuine(public)key)if not(is_genuine(key))に変更するには、どこかを少しだけ裏返します)...

したがって、攻撃者が確認コードを見つけられないようにする必要があります。それだけでなく、あなたは彼が確認コードを飛び越えて興味深い部分に飛び込むことを不可能にする必要があります。アプリケーション全体を難読化する必要があります。しかし 不可能ではないとしても難読化は難しい

難読化を利用できる方法は2つだけです。

  • 誰もあなたのアプリを気にしないなら、おそらく誰もそれを解読しようとしないでしょう。 (欠点:あなたもお金を稼いでいない。)
  • あなたはそれに多くの努力を注ぎ、それが少しの間だけ続くことを望みます。各リリースには多大な労力を注がなければならないことに注意してください。同じ難読化手法で多くのソフトウェアがリリースされている場合、誰かがそれを解読する方法を見つけ、すべてのソフトウェアが公開されます。

難読化のサクセスストーリーについては、 (Gavin DoddのゲームについてのストーリーSpyro:YOTD を読むことをお勧めします。重要な点は、多くの労力を費やしたこと、その目的は数か月の間クラックを遅らせることだけだったこと、そして各ゲームの攻撃に限られた時間しか費やさずに停止する攻撃者の心理に一部依存していたことです。彼らが最初のハードルを通過するとすぐに。

ほとんどの場合、難読化はそれがあなたに利益をもたらすことができるよりもはるかに多くの費用がかかります。

それで、あなたは何ができますか?記事でアドバイスされているように、デバイスで購入を確認せず、管理下のサーバーで確認します。これは、購入の結果がサーバーからのものである場合にのみ役立ちます。たとえば、購入が追加のコンテンツまたは機能に対するものである場合、レシートはサーバー上のユーザーのアカウントのコンテンツのロックを解除する必要があり、アプリはサーバーが許可するコンテンツをダウンロードします。

どの暗号化を使用しても、それはクライアントのデバイス上にあるため、暗号化を解除できます。 DRMシステムと同じ問題が発生しています。これにより、ユーザーに渡すanythingを変更できます。

アプリケーションのセキュリティが公開鍵の機密性に依存している場合、アーキテクチャに根本的な欠陥があり、別の角度から問題に対処する必要があります。

ユーザーがパブリックキーを変更できないようにして、ユーザーがカスタムのプライベートサーバーを使用できるようにするだけの場合、できることは、それを難読化して最高のものを期待することです。

10
Polynomial

@Polynomialはいつものようにほとんどそれを釘付けにしました、しかし彼がobfuscateによって意味するもののいくつかの拡張のために;

Androidのドキュメントが示唆しているように、公開鍵をバイナリから引き出すのが少し難しいようにしたいと思います。基本的に2つの保護層があります。

  1. ある程度複雑なアプローチを使用して、実行時にキーを作成します。 XORは良いです。ある種の反復は良いです。転置と置換も良いです。
  2. キー導出メカニズムを難読化します。これはつまり、コードに anti-debugging 手法を採用することを意味します。この程度まで進んでいる開発者はほとんどいませんが、それはすべて役に立ちます。
7
lynks