9

ユーザーがエンドツーエンドの暗号化を使用してデバイス間で通信できるアプリを作成しています。これには libsodium 暗号化ライブラリを使用します。非対称暗号化関数 crypto_box(...) には、引数の 1 つとして nonce が必要です。

ノンスの処理方法について少し混乱しています。ある人へのすべてのメッセージは、異なるナンスを使用して暗号化する必要がありますか? 攻撃者が使用されたナンスの 1 つを再び使用できるパブリックアクセスのあるサーバーに使用されたナンスを保存する必要があるため、これは正しくないようです。

A から B に送信されるすべてのメッセージが異なるナンスを持つだけで十分ですか?それとも、A から B にメッセージを送信するために使用するナンスを、C から B に送信するために使用する必要はありませんか?

誰かが私にこれを説明してもらえますか。

4

2 に答える 2

6

特定の共有秘密鍵を使用して送信されるすべてのメッセージには、一意の nonce が必要です。nonce は秘密である必要はありません。シンプルなカウンターで十分です。ノンスの 1 ビットを変更すると、同じメッセージが 2 回送信されたとしても、暗号文がまったく異なるものに見えます。

共有シークレットとは何ですか? (A の秘密鍵、B の公開鍵) または (A の公開鍵、B の秘密鍵) から計算された鍵です。A と B は、持っているものに基づいて異なる計算を実行しますが、最終的に同じ共有シークレットになります。

で使用される共有シークレットcrypto_boxは 256 ビット長です。これは巨大です。共有シークレットは「会話」ごとに一意になると安全に考えることができます。

したがって、(A, B)、(A, C)、および (C, B) は、同じノンスを使用して安全にメッセージを交換できます。しかし、A が特定の nonce を使用して B にメッセージを送信した場合、B は同じ nonce を使用して A にメッセージを送信できません。ノンスは、A と B の間の会話中に交換されるすべてのものに対して一意である必要があります。

したがって、単純なカウンターで問題ありません。A に偶数を選択させ、奇数を B に任せ、メッセージが送信されるたびに nonce を 2 ずつ増やして、準備完了です。

しかし、構築に使用される暗号crypto_boxには、実際には非常に大きなナンスがあります。192 ビット。

つまり、私が書いたことをすべて無視して、メッセージを送信するたびにランダムなノンスを選択するだけであれば、衝突が発生する確率は非常に小さいため、実際には決して起こらないことを確信できます。

Sodium に含まれる一部のストリーム暗号 (AES128-CTR、ChaCha20、Salsa20) はナンスが短く、衝突を避けるためにカウンターが必要です。これが、ドキュメントの「高度な」セクションにある理由です。

しかし、crypto_boxと を使用するとcrypto_secretbox、毎回 ( randombytes_buf(nonce, sizeof nonce)) ランダムなノンスを選択するだけで安全になります。

于 2015-06-10T22:50:35.037 に答える
6

ある人へのすべてのメッセージは、異なるナンスを使用して暗号化する必要がありますか?

はい。実際、同じ秘密鍵に対して同じノンスを複数使用することは決してありませこれを達成するためにノンスを追跡する必要があるのは事実です。

攻撃者が使用されたナンスの 1 つを再び使用できるパブリック アクセスのあるサーバーに使用されたナンスを保存する必要があるため、これは正しくないようです。

ナンスを公開アクセスのあるサーバーに保存する必要があるのはなぜですか? そして、攻撃者はナンスをどのように「使用」できると思いますか? そのためには、あなたの秘密鍵が必要です。

nonce を秘密鍵と同じ場所に保存できないのはなぜですか?

于 2014-06-12T20:51:03.513 に答える