web-dev-qa-db-ja.com

libsodium secretboxで作業するときにナンスとキーを保存する方法は?

なぜ私が尋ねているのですか?

私は暗号化に非常に慣れていないので(しばらくお待ちください...)、不要な間違いをしないようにしたいと思います。私は多くの調査を行いましたが、他のほとんどのプログラミング関連の質問とは別に、自信を持たせるのに十分な情報を見つけるのに苦労しました。今、物事を正しく行う方法を理解しています。

コンテキストとは

PHP(> 7.2))とMySQLを使用してウェブショップで作業しています。いくつかの個人情報を保存する必要があります。ただし、これには重要なデータ(支払いの詳細など)は含まれません-名前、住所のみそれでも、私はこのデータを暗号化したいと思います-特に経験を積むために、このデータは、管理者からの入力なしで、phpアプリケーションによって入力および読み取られます。

私はオーストリアのプロバイダーであるWorld4Youでこのサイトをホストしています。このための適切なWordはわかりません(英語は私の母国語ではありません)が、この共有ホスティングと呼んでいると思います。しかし、私は他のユーザーが私のファイルにアクセスできる共有ホスティングを読みました-これはここでは当てはまりません。

あなたの答えでは、これらの状況は不変であると考えてください。ホスティングに関しては、セキュリティ関連の改善の余地がかなりあることはよく知っています。そしてもちろん、これに関するあらゆる提案に満足しています。しかし、私もこれらの状況で最高の解決策givenを見つけるのを助けてください。

シークレットボックスを使用する理由

私の研究によると、secretboxに代わるより強力な暗号化の選択肢があります。ただし、この追加されたセキュリティは、不適切な実装によって簡単に損なわれる可能性があります-私のようなアマチュアの場合は特にです。 Secretboxはまだかなり安全ですが、はるかに使いやすく、したがって私の場合は最良の選択です。正しい?

また、libsodiumはPHP(バージョン7.2以降)の一部として提供されます。

私の質問

Libsodium e-bookのおかげで、キーとナンスを生成する方法と、これらを使用してデータを暗号化および復号化する方法がわかりました。ただし、キーとナンスの保存方法はわかりません。

キーはどこに保存しますか?

これまでに見つけた(私の状況を考慮した) "最善の"解決策は、ドキュメントルートの外部にあるphpファイルにキーを格納することです。これは物事を進めるのに受け入れられる方法ですか?私のセットアップに大きな変更を必要としない、より良いオプションはありますか?

ナンスはどこに保存しますか?

私の理解では、ノンスは秘密にされる必要はありません。それで、私はナンスをどこに保管しますか?

例:テーブル列の「名前」、「アドレス」、「メール」の文字列を暗号化する場合、3つのナンスを使用しますよね?それで、私はこれらの3つのナンスをこの同じテーブルの3つの追加の列に格納しますか(これはどういうわけか直感的に「間違っている」と感じます)。それとも別の場所に保管しますか?

どの列タイプを使用する必要がありますか?

私が収集したものから、暗号化されたデータをバイナリタイプの列に格納する必要があります。では、BLOBは正しい選択でしょうか?

また、ナンスを格納するためにどの列タイプを使用する必要がありますか(実際にそれらをテーブルに格納する場合)?

ありがとうございました!

6
wire417

私はエキスパートではなく、以前に暗号で何かをしたことはありません。私は素人です!!!この主題に関する知識や知恵として、私が言わなければならないことをとらないでください。自己責任。

私も同じ質問をしています。多くのドキュメントとF.U.D.誰かがこのようなことを覚えるようにまどろんでください。これは、あいまいさと混乱を介してセキュリティを支援するための意図的なものだと確信しています。

冗談はさておき、同じ道をたどる旅で見つけた、あなたが概説したいくつかの概念をさらに詳しく説明したいと思いました。まず最初に、暗号化の使用とその実装方法はユースケースに直接依存するということです。たとえば、保存されているデータをアドレス指定する場合は、回線を介して秘密のメッセージを交換する場合とは非常に異なるソリューションになります。それらはすべて同じアルゴリズムとツールを使用しますが、アプリの実際の実装は異なります。

次に、(シークレットボックス内の)鍵はあなたの人生の血です。安全に保存し、隠しておく必要があります。また、保存されているデータを保存する場合も永続的です。あなたの例では、ドキュメントルートの外側、またはファイアウォールの背後にあるデータベースに保存するのが最適です。また、多くの実装ではパスフレーズを使用してキーを暗号化します(これはGPG/PGPが行うことです)ディスクに書き込む前にこれを実行してパスフレーズを保存できます(randombytes_buf)環境変数で。

Nonceは、作成された暗号文ごとに暗号化ごとに一意です...エラー..。したがって、上記のケースでは、3つのフィールドすべてを1つの文字列にシリアル化し、それを1つのノンスで暗号化します。ここで、解読(読み取り)するには、ナンスを知る必要があります。ここで、ドキュメントとブログの投稿が面白くなります。私は1つの例( libsodium-wrappers )だけを見て、ノンスバッファーを暗号テキストバッファーと連結して、ナンスをプレフィックスとして1つの大きなバッファーを作成しました。

別の方法は、読者が解析可能な形式で両方をシリアル化することだと思います。これは暗号の世界に対する私の質問です。どちらがより良い輸送方法ですか?

1つの文字列/バイナリペイロード:

nonce
vvvvvv
bada55123456789abcdf
      ^^^^^^^^^^^^^^
      ciphertext

または、シリアル化するときに2つを分離します。

{
  "nonce": "bada55",
  "ciphertext": "123456789abcdef"
}
1
Sukima

Paragonは、専門家ではない人のためにlibsodiumの複雑さを隠すライブラリを作成しました。

初心者はおそらくこのライブラリから始める必要があります: https://github.com/paragonie/halite

1
Blaine Osepchuk