AS3でのソケット接続のためのTLS / SSLプロトコルのサポート





一定のソケット接続を使用するクライアント/サーバーアプリケーション用のFlashクライアントを開発していますが、盗聴トラフィックから身を守ることが重要です。 これを行う1つの方法は、SSL / TLS暗号化を使用することです。 Flashでは、これを行う2つの方法があります。as3cryptoライブラリのネイティブSecureSocketまたはTLSSocketを使用します。 以下に、長所と短所、パフォーマンス、および両方のオプションを実装するときに発生した問題について説明します。



比較チャート



SSL / TLSは、リスニングを防ぐためのソケット上のアドオンであり、参加者(サーバーとクライアント)の認証とトラフィック暗号化の2つの機能を実行します。 ソケットの主な機能は、わかりやすくするために表形式で示されています。







SecureSocketとTLSSocketの比較、「+」-問題は検出されない、「-」-サポートされないか動作しない、「±」-動作するがエラーがあるか、すべての場合ではない、「?」-以前のエラーのために検証できなかった、「-?」-動作していると記載されていますが、確認できませんでした



アイテムの詳細



SecureSocket


Flash Playerの最小バージョン


SecureSocketにはFlash Player 11以降のバージョンが必要です。これはユーザーの75%にのみインストールされます 。 残りの25%については、 とにかくTLSSocketを使用する必要があります



証明書を使用する


SecureSocketはシステムに統合されており、システム証明書ストレージおよびシステムの信頼性を検証する手段、つまり サーバー証明書は実際には認証局を介して検証されますが、 TLSSocketはこれを実行できません。 SecureSocketでは、信頼できると見なされる独自の証明書を追加することもできますが、他のエラー(有効期限、証明書とサーバー名の共通名の不一致)を確認し、何か問題が発生した場合は接続を切断するため、古いテスト証明書(ほとんどすべての開発者が1つを持っています)おそらく動作しません。



SSL


SSL 3.0(以降、SSLとは常にSSL 3.0を意味します)は、強制SSLモードでサーバーでテストされました。 クライアントは、正式に署名された証明書を含め、私たちが試したすべての証明書について、認識されていない証明書検証ステータス(serverCertificateStatus = invalid)で接続を閉じました。 ソケットはパブリックサーバー(google.com、yandex.ru)の443番目のポートに正常に入力されますが、TLSプロトコルが選択される可能性が高いことに注意してください。SecureSocketは、2つのTLSまたはSSL プロトコルのうちの1つのみを使用することを許可しませんswfを実行するブラウザーのTLS / SSL設定に注意してください。 原則としてSSL 3.0が機能しないというふりをすることはできませんが、そのサポートは公式ドキュメントに記載されていますが、機能させることができませんでした。



TLS


TLSはすぐに、両方の証明書で獲得しました。 正常に機能しているソケットを使用して、保護されていないプロトコルと比較して動作速度を評価することができました。



TLSSocket


証明書を使用する


TLSSocketには、証明書の操作にいくつかの弱点があります。



ただし、肯定的な点があります。ライブラリには、無効な証明書(証明書と実際の自己署名証明書のサーバー名の不一致)でも機能するためのいくつかのフラグが用意されています

独自の信頼できる証明書を追加するためのパッチ
DER形式で信頼される外部証明書のサポートを追加する小さなパッチ。 実装では、証明書全体のMD5ハッシュを取得し、サーバーから送信されたものと比較します。一致する場合、証明書は信頼されます。

  1. クラスcom.hurlant.crypto.tls.TLSConfigに、証明書を追加および検証するメソッドを追加します

    /** * Add own your own trusted certificate * @param cert A ByteArray object containing a DER-encoded X.509 digital certificate. */ public function addTrustedCertificate(cert:ByteArray):void { var md5:String = Hex.fromArray(new MD5().hash(cert)); trustedCertificates[md5] = true; } /** * Check whether the certificate is marked as trusted * @param cert X509Certificate object to check */ public function isTrustedCertificate(cert:X509Certificate):Boolean { var md5:String = cert.md5; return trustedCertificates[md5]; }
          
          



  2. クラスcom.hurlant.crypto.cert.X509Certificateで、md5ハッシュと_bytesプロパティ(DERエンコーディングの証明書)にゲッターを追加します。

      private function load():void { ... } else if (p is ByteArray) { b = p; } _bytes = b; ... } private var _bytes:ByteArray; private var _md5:String; /** * get md5 hash for certificate */ public function get md5():String { if(_md5) { return _md5; } if (_bytes) { _md5 = Hex.fromArray(new MD5().hash(_bytes)); } else { throw new Error("get md5: Invalid x509 Certificate parameter"); } return _md5; }
          
          



  3. クラスcom.hurlant.crypto.tls.TLSEngineで、サーバー証明書のプロキシ検証をloadCertificatesメソッド行810 追加します。

      ... } else if (_config.isTrustedCertificate(firstCert)) { certTrusted = true; } else if(_config.trustSelfSignedCertificates ) { // Self-signed certs certTrusted = firstCert.isSelfSigned(new Date); }else { ...
          
          





使用例:

 package { import com.hurlant.crypto.tls.TLSConfig; import com.hurlant.crypto.tls.TLSEngine; import com.hurlant.crypto.tls.TLSSecurityParameters; import com.hurlant.crypto.tls.TLSSocket; import com.hurlant.util.der.PEM; import flash.display.Sprite; import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.SecurityErrorEvent; import flash.utils.ByteArray; public class addcerttest extends Sprite { [Embed(source="cert.pem", mimeType="application/octet-stream")] private static const cert_pem:Class; public function addcerttest() { var cert_pem_bytes:ByteArray = new cert_pem(); var cert_der:ByteArray = PEM.readCertIntoArray(cert_pem_bytes.readUTFBytes(cert_pem_bytes.bytesAvailable)); var config:TLSConfig = new TLSConfig(TLSEngine.CLIENT, null, null, null, null, null, TLSSecurityParameters.PROTOCOL_VERSION); config.addTrustedCertificate(cert_der); var socket:TLSSocket = new TLSSocket(null, 0, config); socket.addEventListener(Event.CONNECT, log); socket.addEventListener(Event.CLOSE, log); socket.addEventListener(IOErrorEvent.IO_ERROR, log); socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, log); socket.connect("my.app.server", 443); } private function log(event:Event):void { trace(event.type); } } }
      
      







SSL / TLS


TLSSocketでは、両方のプロトコルでトラフィックの暗号化が機能しましたが、クライアントでのパケット暗号化は、数分間のクライアント操作後にSSLで壊れます。 ほとんどの場合、ライブラリの何らかの種類のバグが原因で壊れています。 TLSは問題なく機能します。

通常、As3cryptoにはかなり大きなバグのリストがあり、開発者がライブラリの更新を停止したという事実によって問題は悪化しています。



性能



SecureSocket


SecureSocketで新たな問題が発生しました-定期的に(5〜10リクエストごと)、明らかな理由もなく2〜8秒間、ソケットは「それ自体」に入ります。 私は誰もがそのような遅れを持っていると言うことを想定していませんが、さらに、同じサーバーでそれらがありました。 TLSSocketが迅速に機能した、つまり クライアント側のビジネス。 アプリケーションとしてバインドせずに「クリーン」なデモでテストしました。 解析時間のパケットサイズへの依存性を確立することはできませんでした。30バイトから5 kbのパケットを試行しました。ランダムパケットでは異なる時間にフリーズが発生しました。フリーズ中にプロセッサがロードされず、fpsはドロップしませんでした。 パケットの解析自体は高速です。ハングなしでパケットのみを取得する場合、 ソケットSecureSocketの違いはごくわずかですがTLSSocketソケットよりも低速です。 後で対処しようとします 私はまだ迅速に機能するネイティブオプションが欲しいです。



TLSSocket


ここでのas3での実装全体がパケットの解析時間はサイズに直線的に比例し、コアi7での2-7 kbパケット(プロジェクトでは最大)はそれぞれ40-120ミリ秒であったため、ランタイム通知を含む小さなパケットは解析されます(パケットでは5-20ミリ秒100〜500バイト)で、遅延は発生しません。 ユーザーにとって、SSL / TLSの追加は大きなパケットでのみ顕著になります。



SWFレイアウト



すべてのチェックとデバッグが完了したので、アセンブリをhttpサーバーにポストしますソケットポリシーサーバーを構成することを忘れないでください。 アプリケーションを起動すると、両方のソケットが機能しないことがわかります。 それぞれに独自の理由があります: TLSSocket問題4が原因で機能しません-クライアントは接続が確立される前に「ハンドシェイク」の要求を送信します。 SecureSocketを使用すると、Flash PlayerでTLS / SSL接続を開くことが少し難しくなります。TLS / SSLプロトコル経由でサーバーからポリシーファイルを送信する必要があります。 このファイルのディストリビューターの最終決定が必要です。



結論



SecureSocketはシステムに統合されているため、 TLSSocketが誇ることのできない、システム証明書ストレージおよび信頼性を検証するシステム手段と連携できます。 ただし、 SecureSocketの利点はこれで終わりです。 明らかな欠点のうち、着信データの解析時の2番目の遅延、SSL 3.0の破損、および何かが機能しない場合の無音のデバッグは、多くのネイティブas3ソリューションの特徴です。 TLSSocketは、その高速性と、作業中のエラーを修正する(または少なくとも理由を解明する)能力によって区別され、そのソースを提供します。



最後まで読んでくれた人に感謝します。この資料が役に立ち、誰かが時間を節約してくれることを願っています。 タイプミスやエラーは個人的に送ってください。 不正確な点や追加点については、コメントで議論していただければ幸いです。

GitHub as3crypto_patchedにリンクし、記事に記載されているパッチと外部の信頼できる証明書を追加する機能を使用します。




All Articles