web-dev-qa-db-ja.com

OpenSSLで生成された秘密鍵と公開鍵をiOSとAndroidアプリに提供する方法は?

問題の説明は次のとおりです。 サーバー上で生成された個別の秘密鍵と公開鍵をネットワーク経由でクライアントに提供するには(登録後、HTTPS接続を介して)。クライアントはiOSであり、Androidアプリであり、サーバーはPHPのOpenSSLライブラリを使用してキーを生成しています。その後、クライアントはキーの保存に進み、さらなる通信に署名します。
追記:
[1]アプリには、署名を検証するためのサーバーの公開鍵も必要です。
[2]暗号化はキーで行われません。署名するだけです。

アプリにキーを提供して、ネイティブでサポートされている形式でアプリを使用できるようにするための最良の方法は何ですか?これまでに、キーを提供するための多くのフォーマットとファイル構造について読みましたが、この状況を経験した人は誰でも、どのフォーマットが最も手間がかからないのかを案内できますか?

4
kumar

あなたが何を求めているのか完全にはわかりません。アプリが特定の形式をネイティブでサポートしている場合は、それを使用します。質問したい特定のアプリはありますか?

作成しているアプリの単純な形式が必要な場合は、OpenSSH形式は素晴らしく単純です(そして広く使用されている/サポートされています)。また、X.509証明書はもう少し複雑ですが、広くサポートされていますが、それはあなたがやろうとしていることの範囲を少し超えているかもしれません(X.509はPKI [公開鍵インフラストラクチャ]とPMIの完全な仕様です) [権限管理インフラストラクチャ])。

OpenPGPには無料の実装(gnupg)もあり、優れたライブラリサポート/ Nice keyフォーマット(ASCIIアーマーを使用する場合)があります。

[OT]:セミオフトピックのノートでは、秘密鍵をサーバー側で生成してクライアントに提供することは、ほとんどの場合、公開鍵/秘密鍵暗号の目的に反する悪い考えです。代わりに、サーバーの公開鍵を使用してクライアントを事前シードし、クライアントで秘密鍵を生成し、サーバーの公開鍵を使用して接続を確認し(すでにTLSを使用している場合は、この部分を実行した後)、サーバーのクライアントの公開鍵。また、すでにTLSを使用している場合は、なぜ別のレイヤーが必要になるのかわからないので、繰り返しますが、どのようなユースケースを想定していたのかはわかりません。

Unix/Linuxシステムの各キーの例を取得するには:

OpenSSH:ssh-keygen -t rsa -b 2048 -f filename

GnuPg:gpg --keyserver pgp.mit.edu --recv-key 0xEC2C9934 && gpg --armor --export 0xEC2C9934(私の公開鍵をダウンロードして表示します)

X.509:openssl genrsa -sha512 -out keyfile.key 2048は秘密鍵を吐き出します。次に、openssl req -new -key keyfile.key -out keyfile.csrを使用して証明書署名リクエストを生成し、最後に証明書を生成できます:openssl x509 -req -days 1 -in keyfile.csr -signkey keyfile.key -out keyfile.crt

最終的な考え

コメントを読んだ後、あなたはより完全な解決策を探しているようです。私があなたが何を望んでいるかを理解しているなら、理想的な解決策はX.509証明書を使用することだと思います。独自のCA(認証局)を作成するか、信頼できるサードパーティからオンラインで証明書を購入することができます(私は RapidSSL が好きです)。次に、アプリでサーバーからの通信を確認し、ECDH(Eliptic Curve Diffie–Hellman)を使用して共有キーをネゴシエートし、安全な通信を促進できます(フットプリントが小さいため、ECDHは通常のDHよりも高速だと思います)。 。暗号化にはAES256を、メッセージダイジェスト検証にはSHA2を使用すると、安全で十分にサポートされた、適度に低いオーバーヘッドの接続が得られます。基本的にはTLSを使用し、暗号化タイプ、鍵交換メカニズム、およびメッセージダイジェスト機能に対して適切なオプションを選択していることを確認してください。

4
Sam Whited

私はこのセットアップと同様のことを行ったので、OpenPGPよりも標準的なX509 PKIセットアップを使用することをお勧めします。頻繁に使用する場合は、理解するべきことが少しあり、スクリプトを作成する価値がありますが、モデルに適合します。

基本的に、独自の認証局(CA)を作成する必要があります。新しいアプリケーションがオンラインになると、それらは秘密/公開鍵を作成し、公開鍵を証明書にラップして、その鍵の所有者の識別を提供し、それをCAに送信して、証明書署名要求(CSR)で署名します。これは、サーバーで秘密鍵を生成せずに新しい公開鍵を受け入れる標準的な方法です。これは明らかに攻撃ポイントですが、アプリにキーを送信するのと同じリスクがあります。

X509の主な利点は、WebサーバーとHTTPSとの連携です。ほとんどの(/すべての)主要なWebサーバーは、クライアント証明書を受け入れ、サーバーアプリケーションに到達してクライアント固有の情報を得るためにサーバーに公開鍵と証明書名(CN)を渡す前に、CAによって証明書が署名されていることを確認できます。

WebにはX509 CAのセットアップや署名、クライアント証明書の処理に役立つ多くの場所があり、ほとんどが困難ですが、長期的に見るとPGPよりも適していると思います。

質問の詳細に対処するための編集:

サーバーを特定することは、アプリケーションが事前に簡単に認識できるCAを認識し、信頼する必要があることを意味します。 HTTPS経由で接続すると、サーバーが正しいホストexample.comとして提示され、証明書がCAで署名されていることを確認できます。

この方法を使用すると、PEMファイルに秘密鍵と公開鍵を格納するだけで済みます。PEMファイルは、テキストまたはその他のさまざまな形式で、アプリに最適なものに応じて異なります。次に、クライアント証明書としてウェブサーバーへの呼び出しでそれを提供します。これは明らかにhttpライブラリに依存します(Androidやiosについてはわかりません)が、確実に持っています。次に、単純にPOSTまたはあなたが望むことを意味するものであれば何でも要求します。

4
jamielennox