web-dev-qa-db-ja.com

SSL / TLSの計算的にシンプルで軽量な代替品

ターゲットハードウェアはかなり低電力のMCU(ARM Cortex-M3 @ 72MHz、約64KB SRAMおよび256KBフラッシュ)なので、ここで細い線を歩きます。私のボードにはイーサネットがあり、最終的にlwIP(軽量TCP/IP FOSSスイート)が実行されます(現在苦労しています)。ただし、SSL/TLSに代わる超軽量の代替手段も必要です。そのようなMCUのGPL化された複数のSSL/TLS実装を知っていますが、それらのフットプリントは依然としてかなり重要です。他のすべてのことを考えると、彼らは適合していますが、他の人のために余地を残さないでください。

私のトラフィックはHTTPではないので、HTTPSについて心配する必要はありません。また、クライアント/サーバー通信は完全に独自仕様である可能性があるため、非標準のソリューションで問題ありません。ミニマリズムでありながら堅牢である可能性があるものについての提案を探します(弱いセキュリティは価値がありません)、私を助ける代替案-

Encrypt my communication (C->S & S->C)
Do 2-way authentication (C->S & S->C)
Avoid man-in-middle attacks

ARMv7アセンブリレベルでライブラリを最適化することはできないので、プログラミングスキルとGNU-ARMコンパイラの最適化に完全に頼ることができます。上記のように、最良の選択肢となる可能性のあるもののポインタはありますか?

C:クライアント、S:サーバー。私の通信はすべてバイナリデータです。

24
mike.dinnone

編集:少し努力してから、 did を実行できるRAM効率の良いSSLライブラリを再実装します種類はRAM=以下に示す金額です。以前の作品よりもはるかに多くの機能と柔軟性を備えていますが、それでもまだ非常に小さいです。さらに重要なことに、オープンソース(MITライセンス)でもあります。お楽しみください: https://www.bearssl.org/


ARMコード(サム))の約21 kBでSSL/TLSクライアント(またはサーバー)を実装することが可能で、20 kB未満のRAM実行中(*)。私はそれを実行したために実行できることを知っています(申し訳ありませんが、オープンソースではありません)。TLSの複雑さのほとんどは、最初のハンドシェイク中にネゴシエートされるさまざまな種類の暗号化アルゴリズムのサポートに起因します。暗号化アルゴリズムの1つのセットのみに集中すると、コードを非常に小さなものにストリップできます。TLS_RSA_WITH_AES_128_CBC_SHA256暗号スイートで TLS 1.2 を使用することをお勧めします。 RSA、AES、SHA-256の実装のみが必要になります(TLS 1.1以前の場合、MD5とSHA-1の両方の実装も必要です。これは難しくはありませんが、コードの追加のキロバイト数を費やします)。また、あなたはそれを同期させることができ(プレーンTLSでは、クライアントとサーバーは同時に話す可能ですが、それらに強制することは何もありません)、「ハンドシェイク再交渉」部分(クライアントとサーバーpe)を省略できます初期ハンドシェイクをrformしますが、後で接続中にやり直すことができます)。

プロトコル実装の最も難しい部分は証明書です。サーバーとクライアントは、それぞれの秘密鍵を使用して相互に認証します。RSAを使用すると、サーバーはRSA復号化を実行し、クライアントはRSA署名を計算します。これにより、クライアントとサーバーがお互いに公開鍵を知っている限り、認証が提供されます。したがって、それらは send に公開鍵を相互に送信し、 certificates にラップされて、署名されたblobです。証明書は、使用前に検証する必要があります。つまり、 priori 既知の公開鍵(「ルートCA」または「トラストアンカー」と呼ばれることが多い)に関して検証された署名です。クライアントは中間者攻撃を許可するため、サーバーが送信した公開鍵を盲目的に使用することはできません。

X.509証明書の解析と検証は少し複雑です(私の実装では、21 kBのうち6 kBのコードでした)。設定によっては、もっと軽いオプションがあるかもしれません。たとえば、サーバーの公開鍵をクライアントでハードコーディングできる場合、クライアントはその鍵を使用してサーバー証明書を破棄できます。これは「ブロブ」にすぎません。解析の必要がなく、証明書がなく、非常に堅牢なプロトコルです。独自の「証明書」フォーマットを定義することもできます。もう1つの可能性は、 [〜#〜] srp [〜#〜] を使用することです。これは、両方の当事者が共有秘密値(魔法の魔法)の知識に関してお互いを認証する鍵交換メカニズムです。 SRPは、共有シークレットのエントロピーが比較的低い場合(例:パスワード)でも堅牢であることです。 TLS_SRP_SHA_WITH_AES_128_CBC_SHAを使用します。

ここでの要点は、カスタムプロトコルを使用した場合でも、少なくとも堅牢な状態を維持する必要がある場合は、簡略化されたTLSよりも実際には軽量なものは得られないということです。そして、堅牢なプロトコルの設計は簡単ではありませんまったく; TLSは、長年の血と涙によって十分に安全であると見なされるようになりました。したがって、独自のプロトコルを発明するよりも、TLSを再利用する方が実際に優れています。また、これによりコードのテストがはるかに容易になります(既存のSSL/TLS実装と相互運用できます)。

(*)20 KBのRAMのうち、TLSはレコードがそのサイズに達する可能性があると述べているため、着信「レコード」用に16.5 kBのバッファーがあります。クライアントコードとサーバーコードの両方を制御する場合、最大レコードサイズを小さくして、RAM要件を節約できます。レコードごとのオーバーヘッドはそれほど大きくありません。平均で50バイト未満です。 -したがって、4 kBのレコードを使用しても、効率的な通信が可能です。

31
Thomas Pornin

TLSはまだ仕事のツールのようです。暗号を賢く選択し、どの暗号実装がプラットフォームで適切に機能するかをプロファイルします。また、暗号ライブラリの公式実装は、ハッキングのものと比較すると、 John The Ripper のアルゴリズムのようにひどく遅くなる傾向があるため、これらを使用することができます。 MatrixSSL を試しましたか?

3
Marcin

あなたが何をするにせよ、私はしばらくの間存在している既存のプロトコルを使い、独自のプロトコルを発明するのではなく、それを軽くするためにいくつかのオプションを取り除き/ハードコーディングします。

事前共有対称鍵で十分に対応できるほど単純なニーズの場合、TCP/IPスタックにIPSECのサブセットを追加すると、巨大なコードフットプリントなしで実行できるように思えます。相互運用性を維持することさえ可能かもしれません。

同様に、SSLやKerberosを取り除いたものもおそらくオプションです。より洗練された認証やキー管理の側面も、ほとんどの暗号も必要ないからです。

3
frankodwyer

MST(Minimal Secure Transport) https://github.com/DiplIngFrankGerlach/MST をご覧になるかもしれません。

TLSと同じセキュリティが保証されますが、事前共有キーが必要です。また、非常に小さく(1000 LoC未満、AESなし)、したがって専門家が簡単に確認できます。

0
user161352