恐れることをやめ、エンドツーエンドの暗号化を愛する方法







こんにちは、Habr!

最初の投稿へのコメントで、人々 コードのパンとサーカス「成功物語」を要求しました。 そして、最初のものですべてが多かれ少なかれ正常である場合、何かが何らかの形でまだ2番目のものでうまくいかない。 私たちは、あなたが知っているように、人々はすべて若いです。 つまり、今日は少し歩き回って、サービスを使用したエンドツーエンド暗号化の実装について説明します。 サクセスストーリーはどうですか? 私たちのブログで私たちの年が何であるかは、これらと同じサクセスストーリーです。



キー管理



エンドツーエンド暗号化の実装に関する問題の1つは、受信者への暗号化キーの安全な転送です。

問題を解決する最も明白な方法は、公開鍵暗号化です。 システムの各ユーザーは、2つの部分で構成されるキーを持っています。秘密部分(秘密キー)。秘密のままにされ、ネットワーク経由で送信されることはありません。 システムのすべての参加者が利用できるはずの公開部分(公開鍵)。 署名の暗号化と検証は公開鍵を使用して実行されますが、署名と復号化には秘密鍵を使用するのが一般的です。

秘密鍵と公開鍵の定義に基づいて、システムのすべての参加者は公開鍵を使用してメッセージを暗号化できますが、秘密鍵の所有者のみがこのメッセージを復号化できます。



公開鍵スキームを実装する際に最初に考慮すべきことは、公開鍵を第三者に置き換える機能です。 トラフィックを変更できる攻撃者は、アリスの公開キーを傍受し、自分の公開キーに置き換えることができます。 これにより、ユーザーBobは、暗号化されたメッセージをAliceに送信しようとすると、実際に攻撃者のキーで暗号化され、秘密データを解読して読み取ることができます。

このような状況を防ぐ方法の1つは、キーの所有者を一意に識別する機能です。 この場合、キーの変更がボブに明らかになります。 識別子として、電子メールアドレス、電話番号、その他の簡単に認識できる一意の情報を指定できます。 新しいキーを作成するときに指定した識別子は、確認および確認する必要があることに注意してください。 それ以外の場合、各ユーザーがだれでも偽装できるシステムを取得するリスクがあります。



名前を検証するには、ID検証サービスが必要です。 原則として、このようなサービスは、名前として指定された電子メールアドレスまたは電話番号にランダムに生成されたコードを送信し、ユーザーからの確認を待ちます。

ただし、ID検証サービスの使用は、信頼問題を通信チャネルからサービス自体にシフトするだけです。 実際、サービスの所有者が第三者に属すると思われる侵害されたキーを作成することを妨げるものは何もありません。



侵害されたキーの可能性を完全に取り除くには、 キー認証が必要です。

キーの認証は、ボブがアリスに属していると信じているキーが実際にアリスに属していることを確信させる方法です。 キー認証の問題を解決するには、いくつかの方法があります。 その中で最も明らかなのは、個人的な会議中またはより信頼性の高い通信チャネルを使用する際の鍵交換です。 高い信頼性にもかかわらず、この方法は常に現実の世界で実装されているわけではありません。 したがって、次のキー認証方法のいずれかが使用されます。

最初の方法は、信頼できる認証局を使用することです。 システムの特定のユーザー(信頼できるセンター)が無制限の信頼を持ち、キーの証人として機能できる場合。 このようなシステムのキーは、信頼できるセンターの署名がなければ、信頼できるとは見なされません。

2番目の方法は、信頼ネットワークを使用することです。 同時に、システムの各ユーザーは、他のユーザーのキーに署名する権利を持っているため、キーが実際に指定された所有者に属していることを確認できます。 証明するキー署名が多いほど、彼はより信頼できます。



したがって、キーを作成、保存、および転送する手順には、Virgil Securityで簡単に回避できるいくつかの落とし穴があります。



Virgil Security



Virgil Securityは、無料の暗号化サービスのセットを提供します。このサービスを使用すると、多くのセキュリティ問題を解決できます。 特に、鍵管理の問題。

現在、Virgil Securityは次のとおりです。

  1. Virgil暗号ライブラリは、mbedTLSを介したオープンソースシェルであり、すべての標準暗号化および署名アルゴリズムを使用できます。 また、ハイブリッド暗号化アルゴリズム(ECIES)も追加されます。 Virgil暗号ライブラリを使用すると、既存のデータを復号化せずに将来アルゴリズムを変更できます-暗号の俊敏性の原理です。
  2. Virgil IDサービス -電子メールアドレスの有効性を確認できるオープンAPIを備えたID検証サービス。 サービスは、指定された電子メールに秘密コードを送信します。このコードは、アドレスの所有権の事実を確認するためにユーザーが入力する必要があります。
  3. Virgilキーサービス -信頼性が高く手頃な価格の公開キーストアで作業できるようにする公開キーサービス。 ストア内の各キーは、VirgilCardと呼ばれる特別なデータ構造に関連付けられています。 VirgilCardには必ず、一意のカード識別子(ID、キーホルダー識別子)、電子メールアドレス、電話番号など、およびキーの作成日が含まれます。 Virgilキーサービスを使用すると、システムユーザーの公開キーをすばやく見つけたり、キーが侵害されたカードを削除したりできます。
  4. Virgil秘密鍵サービスは、秘密鍵のダウンロード、ダウンロード、削除を行う秘密鍵サービスです。 秘密鍵にアクセスするには、接続されているVirgilカードの所有権を確認する必要があります。


上記のすべてのサービスには、幅広い市販のSDKが用意されており、情報セキュリティに関連する最も広範なタスクを解決するために使用できます。



Virgilサービスとエンドツーエンド暗号化



それでは、少し時間をかけてみましょう。 Virgil Securityを使用して、信頼できるエンドツーエンド暗号化を実装する方法を示します。 これを行うには、次のスキームを実装します。



暗号化はECIESスキームを使用することに注意してください。 つまり、メッセージは一時的な対称キーを使用するAES対称アルゴリズムで暗号化され、受信者の秘密キーでのみ復元できます。 暗号化は、受信者の公開鍵を使用して実行されます。



Virgil Securityサービスを使用するには、シークレットトークンと公開/秘密キーのペアを取得する必要があります。 これを行うには、 Virgil Security Webサイトで登録します。 その後、e2eeの実装に進みます。



  1. NPMを使用してVirgilSDKをダウンロードしてインストールします。

    npm install virgil-sdk
          
          





  2. Virgil Securityサービスで作業を初期化します。

     var virgil = new VirgilSDK("%ACCESS_TOKEN%");
          
          





  3. キーペアを生成します。

     var keyPair = virgil.crypto.generateKeyPair(); console.log(keyPair.publicKey); console.log(keyPair.privateKey);
          
          





    そして、この結果が得られます。
    -----公開キーの開始-----

    MFswFQYHKoZIzj0CAQYKKwYBBAGXVQEFAQNCAAQO8ohmBRyclmcfQ38Lwmvv4Cau

    jyX6vWn8kJrR0RRfFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    -----公開キーの終了-----



    ----- ECプライベートキーの開始-----

    MHkCAQEEIFB + lOUvbb4WX + e3zLkAcYpvZR3qpQI8Ru / tcnciCMkIoAwGCisGAQQB

    l1UBBQGhRANCAAQO8ohmBRyclmcfQ38Lwmvv4CaujyX6vWn8kJrR0RRfFQAAAAAA

    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    ----- ECプライベートキーの終了-----



  4. 公開鍵を公開します。 これには、キーの所有者の身元を確認する検証トークンが必要です。 検証トークンを取得する方法は2つあります。1つ目は、Virgil Identityサービスを使用する方法です。これは、キーの所有者が実際に電子メールアドレスにアクセスできるかどうかを確認し、検証トークンを生成します。 または、アプリケーションの秘密キーを使用し、それを使用して検証トークンを自分で生成できます。 この場合、開発者はサードパーティの認証サービスを信頼する必要がなくなります。 取得した検証トークンを使用して、サーバーに公開キーを保存します。

     var options = { public_key: keyPair.publicKey, private_key: keyPair.privateKey, identity: { type: 'member', value: 'Darth Vader', validation_token: '%VALIDATION_TOKEN%' } }; virgil.cards.create(options).then(function (card){ myCard = card; console.log(card); });
          
          





    その結果、公開鍵サーバー上に次のフォームのマップが作成されます。
     { "id":"3e5a5d8b-e0b9-4be6-aa6b-66e3374c05b3", "authorized_by":"com.virgilsecurity.twilio-ip-messaging-demo", "hash":"QiWtZjZyIQhqZK7+3nZmIEWFBU+qI64EzSuqBcY+E7ZtKPwd4ZyU6gdfU/VzbTn6dHtfahCzHasN...", "data":null, "created_at":"2016-05-03T14:34:08+0000", "public_key":{ "id":"359abe31-3344-453a-a292-fd98a83e500a", "public_key":"-----BEGIN PUBLIC KEY-----\nMFswFQYHKoZIzj0CAQYKKwYBBAGXVQEFAQNCAAQ...", "created_at":"2016-05-03T14:34:08+0000" }, "identity":{ "id":"965ea277-ab78-442c-93fe-6bf1d70aeb4b", "type":"member", "value":"Darth Vader", "created_at":"2016-05-03T14:34:08+0000" } }
          
          











  5. 暗号化されたメッセージが送信されるチャネルを作成します。 見た目ほど難しくありません。 最近、特にIPメッセンジャーの実装用のAPIを提供するTwilioのパートナーになりました。 エンドツーエンドの暗号化機能が組み込まれた既製のIPメッセンジャーの例は、 ここにあります

     // Create a Channel twilioClient.createChannel({ friendlyName: 'general' }).then(function(channel) { generalChannel = channel; });
          
          





  6. 秘密のメッセージを送信するために、対話者の公開鍵を見つけ、それを使用して暗号化します

     // Receive the list of Channel's recipients Promise.all(generalChannel.getMembers().map(function(member) { // Search for the member's cards on Virgil Keys service return virgil.cards.search({ value: member.identity, type: 'member' }) .then(function(cards){ return { recipientId: cards[0].id, publicKey: cards[0].public_key.public_key }; }); }).then(function(recipients) { var message = $('#chat-input').val(); var encryptedMessage = virgil.crypto.encryptStringToBase64(message, recipients); generalChannel.sendMessage(encryptedMessage); console.log(encryptedMessage); });
          
          





    暗号化されたメッセージは次のとおりです。
    MIIDBQIBADCCAv4GCSqGSIb3DQEHA6CCAu8wggLrAgECMYICvDCCAVoCAQKgJgQkMDg3YjgwYmMtMzNjYi00MTI1LWI4YTgtYTE

    3OTEwM2Y3ZjRkMBUGByqGSM49AgEGCisGAQQBl1UBBQEEggEUMIIBEAIBADBbMBUGByqGSM49AgEGCisGAQQBl1UBBQEDQgAEcd

    8fhKqYlZxvcmmodg7Z3PNhE1LXLJqobouEcRfZaRMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAYBgcogYxxAgUCM

    A0GCWCGSAFlAwQCAgUAMEEwDQYJYIZIAWUDBAICBQAEMEaJMAvX7S+52BpI5hYyFOc0noIc+qdFFrQanNAtNGBAX/Pxeg5yJ2iA

    JijyZ8ut9zBRMB0GCWCGSAFlAwQBKgQQ81bklcNOyU/QTatCigSzoAQwHnAcbXk0daExIIS+sr6aIvVuF/o6j+1Rs5bvq2WVN41

    k/Oir5x7KZTSR7v3nx+fTMIIBWgIBAqAmBCRmNzM4YTUwNi1hMDYwLTQ1MDgtYTJkYS04NjY1NjZlYzg0ODMwFQYHKoZIzj0CAQ

    YKKwYBBAGXVQEFAQSCARQwggEQAgEAMFswFQYHKoZIzj0CAQYKKwYBBAGXVQEFAQNCAARJ5C3hsYuI2Sf14k60Dz5Mv5yD/AsVA

    zPfsmlreGTC2gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMBgGByiBjHECBQIwDQYJYIZIAWUDBAICBQAwQTANBglg

    hkgBZQMEAgIFAAQwhu7WM1rff9RYsQ+dmfX9Os3Irwm4cm5bIvUlcGXlCfmEsrjTyTg5MGjYLtxbYtL9MFEwHQYJYIZIAWUDBAE

    qBBCfKdP/gZnkVwJvv4Hdf2eWBDC3czBjV/yPGeGTqBIilHSsrqwK7lVMTBuKR+mR3eNdh+yBIAcOk4rveSUbDuWagDIwJgYJKo

    ZIhvcNAQcBMBkGCWCGSAFlAwQBLgQMfjkCvK3UgXdorcYUmtCHHuSm4yfBacMsniMADAeos7qN7OmNsFU1









  7. 受信者は秘密鍵を使用してメッセージを復号化します。

     // Listen for new Messages sent to a Channel generalChannel.on('messageAdded', function(message) { // Decrypt the Message using card id and private key values. var decryptedMessage = virgil.crypto.decryptStringFromBase64( message.body, myCard.id, keyPair.privateKey ); console.log(message.author + ': ' + decryptedMessage); });
          
          





    次のように表示されます。
    ダースベイダー:ルーク。 私はあなたの父親です!





簡単です。 ほんの数行のコードを書くだけで、キーを認証する機能を備えた完全なエンドツーエンドの暗号化を取得できます。 同時に、Virgil Securityサービスはユーザーの秘密キーにアクセスできないため、機密データを読み取る可能性はありません。



All Articles