暗号化とマスキングによるTwilio Voiceの入力の保護

読む所要時間: 19 分
暗号化とマスキングによるTwilio Voiceの入力の保護
発信者が信頼して入力している機密情報を保護するために、できる限りの対策を講じていますか?
組織がより機密性の高い情報を活用するのに伴い、そのデータの保護はこれまで以上に重要になっています。Twilioは、機密データを保護するためのさまざまな方法を提供していますが、Twilioが責任を持って提供するリソースを実装するかどうかは貴社次第です。
この記事では、Twilioサーバーレス関数、Voice PCIモードで<Gather> TwiMLを使用し、Twilio Programmable Voiceから収集したデータの暗号化とマスキングを行う方法について説明します。
必要なもの
このチュートリアルを利用するには、以下の項目が必要です。
作成する内容
発信者認証を処理するためのシンプルな対話型音声アプリケーションを構築します。関数を使用し、<Gather> TwiMLを介して発信者に以下の機密情報を求めます。
"お客様の4桁の暗証番号(PIN)を入力してください"
"支払いカード番号の最後の4桁を入力してください"
発信者からこの情報を受信するとすぐに暗号化されます。その瞬間から、データは宛先に到達するまで暗号化された状態が保たれます。
実際の実装では、宛先は処理のバックエンドサービスになる可能性があります。ただし、ここでは、別の関数が「ダミーAPI」として機能し、復号化がどのように実行されるかを示します。
さらにVoice PCIモードを有効にし、Voice通話ログ内の収集された情報をマスキングします。
実装前
ソリューションの説明に入る前に、暗号化やマスキングを行わない場合ログがどのように表示されるかを確認します。
Twilio Functionsは、Functionで発生したあらゆるエラーをログとしてTwilio Debuggerに出力します。この例では、特定の数字が入力されていない場合にエラーをログに記録します。Debuggerで受信したエラーには、プレーンテキストのリクエストパラメーターが表示されます。


Programmable Voiceでは、Voice通話ログにも収集された数字がプレーンテキストで記録されます。


この情報は、通話ログまたはDebuggerにアクセスできる場合に参照できます。
実装後
このソリューションを実装した後に表示されるデータは、脆弱性が低くなります。最後に、Functionのログには、より安全で暗号化された値が表示されます。


通話ログには「*REDACTED*」(*マスキング済み*)と表示されます。


関数は、サービス内で作成、格納されます。
Twilio Consoleにログインし、[Functions](関数)タブに移動します。
[Create Service](サービスを作成)ボタンをクリックしてサービスを作成し、「encrypted-gather-sample」のような名前を付けます。
依存関係の追加
このソリューションでは、axiosライブラリを使用して架空のバックエンドサービス(decrypt-gather関数)にリクエストを送信し、処理を実行します。
axiosをサービスの依存関係として追加します。


環境変数の作成
このソリューションでは、機密データの暗号化/復号化に使用する秘密鍵が必要です。
鍵を格納する環境変数をサービス内に追加します。


テスト目的では、次の32バイトの秘密鍵を使用できます。
AES暗号化関数の作成
まず、対称鍵暗号を使用してデータの暗号化と復号を処理する関数を作成します。
Node.js Crypto
Node.jsは、Cryptoと呼ばれる組み込みの暗号化モジュールを提供しています。Cryptoには、createCipheriv()やcreateDecipheriv()などの、使用するブロック暗号アルゴリズムの種類を指定できる便利なメソッドが複数用意されています。
GCMブロック暗号
AESと呼ばれるAdvanced Encryption Standardは、暗号化アルゴリズムを使用してデータを保護する技術です。AESは、さまざまな利用モードにより実現できます。
このソリューションでは、GCM(ガロアカウンターモード)を使用します。これは、速度と強度を高めるために推奨される対称鍵暗号方式のブロック暗号です。
コード
以下のコードを使用して、AESという名前の新しい関数を作成します。
この関数は、同じサービスの別の関数内からのみ使用されるため、可視性を「Private」に設定します。


encrypted-gather関数の作成
次に、機密性の高い<Gather>操作を実行する関数を作成します。この関数は、以降の手順で着信電話番号音声Webhookとして設定します。
この関数により、発信者が入力した番号は受信されるとすぐに暗号化され、暗号化された状態で最終的な「宛先」関数に送信されます。
コード
以下のコードを使用して、encrypted-gatherという名前の新しい関数を作成します。
この関数はTwilio内から呼び出され、X-Twilio-Signatureヘッダーで保護できるため、「Protected」に設定します。


暗号化の方法
一番上にある以下の行では、前のステップで作成した関数をインポートしています。
次に、環境変数から取得して、秘密鍵を定義します。
最も重要なポイントとして、すべての機密情報をencrypt関数でラップします。(この場合、<Gather>で収集された情報はDigitパラメーターとして渡され、イベントオブジェクトからアクセスできます。)
これにより、収集された情報の暗号化が処理されます。
decrypt-gather関数の作成
最後に、機密データを復号化する方法を示す関数を作成します。
本番環境では、ビジネスニーズに基づいて発信者情報を処理するバックエンドサービスへの要求が発生する可能性があります。
このソリューションでは、3番目の関数がこのデータを処理する「バックエンドサービス」として機能します。この関数は、暗号化された数字を受け取り、さらに処理するために復号化します。
コード
以下のコードを使用して、decrypt-gatherという名前の新しい関数を作成します。
この関数は架空の外部サービスとしての役割を果たすため、可視性を「Public」に設定します。


そのほかの構成
電話番号Webhook
簡単にするために、この関数を電話番号に直接接続します。
電話番号を設定するには、次の手順を実行します。
Twilio Consoleから、[Phone Numbers](電話番号)セクションに移動します。
電話番号を選択し、[Voice & Fax](音声とファックス)セクションまでスクロールします。
[Voice Configuration](音声設定)の[A call comes in](着信)Webhookとしてencrypted-gather関数を設定します。
変更内容を保存します。


PCIモードを有効にする
あと少しで完了です。関数の安全性は確保できましたが、Twilioには収集された数字がプレーンテキストで残される場所がもう1つあります。それがVoice通話ログです。
以下は、暗号化された<Gather>ソリューションが実装された着信通話のTwilio Consoleからのスクリーンショットです。関数ではデータが保護されていますが、Voiceでは保護されていません。


PCIモードを使用すると、このデータを通話ログに表示しないようにできます。アカウントでPCIモードを有効にすると、<Gather>操作でキャプチャされたすべてのデータがマスキングされます。


機密情報を安全にキャプチャすることに本気で取り組んでいる場合は、
Twilio ConsoleでTwilio Voice設定に移動します。(左側のナビゲーションペインで、[Voice](Voice) > [Settings](設定) > [General](全般)をクリックします。)
[Enable PCI Mode](PCIモードを有効にする)ボタンをクリックします。
変更内容を保存します。


通話の発信
いよいよ最後の審判となりました。電話番号にテスト通話を発信しましょう。
ここからは2つの経路があります。
「クレジットカード」の下4桁に1234を、固有のPINに4321を入力した場合、通話でダミーのアカウント情報が返されるのが聞こえます。これは、成功したAPI応答の例です。
他の数字を入力すると、既知のユーザーではない動作となり、404の応答が返されます。これは、失敗したリクエストの例で、Twilio Debuggerにエラーが記録されます。
動作確認方法
失敗する場合の経路をたどり、Twilio Consoleでエラーログを確認します。
404のエラー応答が返された場合、Functionsの82005エラーと以下の詳細が表示されます。


この結果は良好です。暗号化がないと、応答が失敗した場合、これらの変数がプレーンテキストで記録されます。しかしここでは、データはより安全で暗号化された形でログに記録されます。
さらに通話ログに数字が「*REDACTED*」(*マスキング済み*)と表示されていることも確認できます。
これで安全でしょうか?
(オプションのPCIモードの手順を含め)このチュートリアルに従うと、データがTwilioのエコシステム内のすべての場所でプレーンテキストでログに記録されることがなくなります。Twilioの誰も機密データを復号化することはできないため、デフォルト状態よりもセキュリティが強化されています。
ただし、暗号化と復号化に使用される秘密鍵は、サービス上の環境変数として保存されています。つまり、Twilio Functionsへのアクセスを許可したユーザーは、鍵を抽出し、値の復号化を試みることが可能です。
最終的な推奨事項
提供されているサンプルコードを変更する場合、Functionsはコンソールの警告とエラーを内部TwilioシステムとTwilio Debuggerに一定期間保持することに注意してください。
機密性の高い暗号化されていないデータでは、次のコンソールロギング方法を使用しないでください。
まとめ
このレッスンでは、<Gather> TwiMLから収集されたデータを、サーバーレス関数による暗号化とVoice PCIモードによるマスキングで保護する方法を学習しました。
発信者から支払いを受け取りたい場合は、完全にPCI準拠のTwilio <Pay>機能を検討してください。
TwilioのPCIコンプライアンスの詳細については、ドキュメントと責任マトリックスをご覧ください。
ユーザーは、秘密が守られると信頼して機密情報を入力します。処理するデータを保護するためにできる限りの対策を行うことで、その信頼を尊重し、維持することを確認してください。
Bry Schininaは、個人情報を公開しない企業に高く評価されている開発者兼教育者です。彼女はTwilioのテクニカルリード兼シニアテクニカルアカウントマネージャーとして、複雑な問題を解決し、デジタルエンゲージメントプラットフォームでの組織の成功を支援しています。連絡先はbschinina [at] twilio.comです。