誰でも書き込み可能なディレクトリを提供するファイルシステムはありますが、ディレクトリの所有者だけがファイルを読み取ることができますか?理論的には、書き込み中に公開鍵を使用して暗号化することで実行できますが、対称ディスク暗号化よりもはるかに複雑であることがわかります。目的は、他の誰もがファイルを入れることができる独自のディレクトリ、つまり一種の安全なメッセージングシステムを、ファイルシステムレベルで持つことができるようにすることです。
誰も(rootでさえ)ではありませんが、所有者にはファイルの読み取りを許可する必要があるため、アクセス権は役に立ちません。システムがキーロガーなどから保護されているとしましょう。
当然のことながら、rootユーザーは実行中に暗号化を回避してローカルで暗号化できます[1]。つまり、2時間または2週間すべてのデータを復号化したいマシンを完全に制御できる敵をターゲットにしているafterデータが保存された。また、ユーザーには書き込み専用アクセス権が必要です。
定期的なファイルベースの暗号化でアクセス制御とcronjobを使用することをお勧めします。ランダムキーを使用した対称暗号化と非対称キーを使用したキー暗号化。単純なGPG暗号化では、このハイブリッドアプローチが自動的に使用されます。暗号化したファイルとステージング領域のファイルを分離するには、異なるパーティション/フォルダーを使用する必要があります。
ファイルベースの暗号化は、ファイル名とメタデータの漏洩により、ブロック層の暗号化ほど安全ではない場合があります。しかし、それはまた、ユーザーが自分のファイルや他の人のファイルを上書きする可能性があるという問題からあなたを救います。あなたのシナリオから、私はあなたがそれが起こることを望まないと思います。
[1] rootはrootではないことは知っていますが、投稿者はここではアクセス制御に依存したくありません。
私の知る限りでは、このようなスキームは、フルブロックレベルのRSAのみの非ハイブリッド暗号を使用する汎用オペレーティングシステムの汎用ファイルシステムでは使用できません。これは、ソフトウェアでのRSAのような操作は、通常、対称の対応物よりも遅く、多くの実装の追加が必要であり、ユーザーランドアプリケーションがこの目的に十分である場合は不要であると考えられているためです。 Linuxカーネルおよびその他のカーネルは、ユーザー空間での幅広い汎用アプリケーションのサポートに関係しているため、平均的な汎用ユーザー機能に不要なものは通常含まれていません。しかし、これはあなたがそれを行うことができないと言うことではありません。 人々はカーネル空間にWebサーバーを実装しています。 必要に応じてこれを行うことができます。
私のすべての基地をカバーするだけです。明らかに、カーネルはオプションで、ハードウェア支援暗号化を提供する可能性のあるものを含む、多くのハードウェアをサポートします。この場合、あなたの人生はかなり簡単になります。
PGP/TLSなどが実装するハイブリッド方式には、対称鍵が本来暗号化されたデータの読み取り/書き込みであるという弱点があります。これを傍受できれば、データを読み取ることができます。これは間違いなく難しいことですが、可能です。ファイルシステムでは、読み取り/書き込みシステムコールの暗号化されていないデータがバッファーに含まれているため、rootであれば傍受できるため、作業が楽になります。
パブリックキー暗号化によってこの形式のアクセス制御(書き込み、読み取りなし)を技術的に実装できるのに、なぜ地球上でそれが行われていないのか、なぜ地球上で質問しているのかと思います。はい、なぜブロックごとのRSAを行わないのか、お答えしたいと思います。したがって、2つのセクションで:
RSAがカーネルに含まれていない理由について
Linuxカーネル(またはおそらくWindowsカーネル)にRSAの実装がないことを知って驚くかもしれません-私はそれがユーザー空間にあるに違いないと思います)。
まず、カーネルの内容を見てみましょう: Linusのメインツリーの暗号化フォルダーです 。非対称アルゴリズムではありません。ここでファイルシステムについてはまだ話し合っています。
次のステップでは、RSAをどのように実装しますか。レジスタレベルでは、x64(AMD64/EM64T互換など)プロセッサは、レジスタごとに正確に64ビットを保持できます。これが、uint32_t
にuint64_t
やstdint.h
のような型があり、整数オーバーフローが発生する理由です。
これがまったく関連している理由を十分に理解していない場合、RSAキーでは特定のビット長の係数を生成する必要があります。 2048をお勧めしますが、1024を因数分解するのは十分困難です(ここと暗号化の両方の因数分解についてのトーマスポルノの投稿を検索してください)。 2048ビットとしましょう。お気づきかもしれませんが、単一のレジスタでは、実際にその数を格納する方法はありません。ですから、レジスターにロードして操作するために少し詰め込みましたね。
では、RSAに必要なサイズの整数をどのように処理すればよいでしょうか。たくさんの64ビットブロックをつなぎ合わせるのが基本的な答えです。 x86プロセッサは、キャリー付き加算の略であるadc
などの操作をサポートします。最上位ビットが一緒に設定されていてオーバーフローする2つのレジスタを追加すると、キャリーフラグが設定され、次に実行するadc
で最下位ビットに1が追加されます。
この事実により、任意の精度の演算に近づくことができます。さて、必要なのは、乗算の片側とその結果を格納するための32ビットの64ビットメモリブロックと、もう1つの数値用の64ビットのx
ロットだけです。これにより、実際に係数を生成することができます。
この理論を少しスピードアップしましょう。さもなければ、私たちは一晩中ここにいます。加算は基本的にO(N) bignumライブラリでそれを見る方法です。乗算や指数のようなものはO(N) if演算子の1つは単一のリム(64ビットのチャンク、リムはその大きな数の項)ですが、乗算や除算などの2つの任意の数値の演算は常に悪い結果になります。これを高速化するために、多大な努力が費やされています。アルゴリズムとそのランタイムについて私が知っている最良の要約は、次の場所にあります: Modern Computer Arithmetic 。ただし、実際には非常に理論的で、アルゴリズムにこだわっており、 Seminumerical Algorithms = Don Knuthによるよりわかりやすい紹介が含まれています。
現在、bignum操作は高速です。ばかげて速いような、ただ速いだけではありません。驚くほど速い。プラットフォームごとに最適化されたループ展開されたハンドアセンブリー。 GNU MP は、地球上で最も高速な汎用bignumライブラリと広く見なされており、Mathematica、Maple、Pari/GPなど、任意の精度の計算を行うすべての人が使用しています。 GPGもOpenSSLも独自のbignum実装を優先してこれを使用していることがわかりましたが、それは彼らの選択です。
対照的に、SESを展開してキーを展開すると、AESは実際には2つあります。つまり、(SBox)に追加したことのないハッシュテーブルです(したがって、常にO(1))になります。キー拡張用のルックアップテーブル(O(1))およびいくつかのxor-ing)。
したがって、AESと比較して言うのは公平だと思います。RSAはかなり遅いですね。操作ごとの計算コストは高くなります。
編集私は、なぜあなたがこれをしないのかについて、私の心の中で別の理由で目覚めました。 this link を参照してください:
Linuxカーネルコードとデータはスワップ可能ではなく、スワップに移動することはありません。
そのため、物理メモリに常にbignum、RSA実装、およびキーを含めるように強制しているため、ユーザーランドアプリケーションの余地が少なくなり、より多くのスワッピングが強制されます。
これらはカーネルにとって大きな問題です。カーネルの仕事は、できる限り効率的にすることです。とても簡単です。これにより、実際には、固定スタックサイズやlibcのほとんどがカーネルスペースに対して過剰と見なされるなど、カーネル開発にいくつかの制限が追加されます。また、カーネルでも 浮動小数点演算を使用しないでください です。私が言っていることを明確にしましょう:カーネルにRSAを実装することは完全に技術的に可能ですが、実際には、これらすべての効率性の節約の犠牲が最終的に行われるユーザーランドではRSAが優れているため、誰もそれを行いません。
また、RSAはブロックレイヤーストレージにあまり適していません。誰もが始める前に、これが悪い考えであることは必ずしも明らかではありません。実際にread前回リンクしたディスカッション を見てみましょう。そこでトーマスの答えを直接引用する:
このようなRSA-with-CBC暗号化を適切な心構えで行う人はいません。理由は次のとおりです。
- 安全であると見なされるのに十分な精査を受けていない。
- サイズのオーバーヘッドは、暗号化されたメッセージがプレーンテキストメッセージよりも約9.4%長くなることを意味します。
- RSA暗号化はそれほど高速ではありません(最近のCPUは、たとえば、毎秒2 MBのデータをその方法で暗号化することに成功します)。
この最後の理由は最も頻繁に引用されていますが、私の意見では、3つの中で最も説得力がありません。
これは最も明らかな欠点であるため、主に最後の問題を扱いましたが、それが問題ではなく、ブロックレベルで比較的遅いことで満足していると仮定すると、 veには、保存する1バイトあたりのオーバーヘッドが大きいという事実もあります。ストレージデバイスを大幅に効率的に使用するわけではありません。
これらすべてをで警告します。必要な場合は、技術的に可能です。これを止めることは何もありません。私はそれがなぜ行われなかったのかを実際に説明しようとしているだけです。
つまり、これはブロックごとのRSAです。他の誰もが怒鳴り回るようになっているので、代わりにRSAを使用して少量の本当に価値のあるデータ(AESまたはその他の対称鍵)を取得することもできます。これは機能します。これがTLSの仕組みです。これは、PGP/GPG/OpenPGPおよびインターネット上の他のほぼすべての暗号化プロトコルが機能する方法です。アイデアは、遅いRSAを使用してキーを暗号化し、それを受信者(暗号化を解除できる唯一の人)に送信すると、対称キーを持ち、オーバーヘッドを大幅に削減して大量のデータ転送を実行できることを前提としています。すべてのアルゴリズムの使用。
同じOSの暗号とキーは問題ないが、完全に安全ではない理由
それでは、オペレーティングシステムについて説明しましょう。あなたのコンピュータは、ハウスメイトが住み、家主に住んでいる家のようなものです。家主はカーネルであり、ハウスメイトはプログラムです。今、あなたのシステムを達成するために、ボブはあなたであり、これが起こることを確認したいです。そこで、彼は2つの金庫を購入し、アリスとキャロルに南京錠を製造し、それぞれに金庫を購入するように指示します。一方、彼は自分の金庫の1つの組み合わせを発明し、それを設定して金庫を廊下に置きました。次に、その組み合わせを保護するために、彼はそれを書き留めて、アリス、キャロル(および自分)のそれぞれに、その組み合わせのコピーを自分の金庫に入れて、自分の金庫をそれぞれ南京錠でロックするように依頼します。したがって、廊下にある金庫を開くには、アリスはまず自分だけの鍵を持っている自分の金庫を開けてから、その組み合わせを読んで金庫をロックし、廊下にある金庫を開ける必要があります。
イブは邪悪な同居人であり、非常に怒っています。彼女は他の人の部屋に入ることはできませんが、家主はどこにでも行くことができるので、それを行うように家主に説得することができます。彼女がする必要があるのは:
そのような単純な。私の元の答えからの最高のビットはこれでした:
理論的には、誰かがrootまたはAdministratorに到達するとすぐに、OSの戦いは失われます。
これとは対照的に、ネットワークサービスは次のように機能します。ボブはジョージにメッセージを投稿したいと考えています。それで、彼はジョージに彼にポストで南京錠を送るようにさせます。ジョージは、両者が完全に信頼する家主と暮らしています。それで、ボブは金庫の組み合わせを廊下に置いてそれを書き留め、金庫に入れ、それにゲルジュの南京錠をかけ、両方を郵便配達員に渡します。彼は郵便配達員を少しは信用していませんが、すぐに郵便配達員をドアの近くまで招待することはありません。玄関で彼がする何かが彼を引き渡さない限り、または金庫や南京錠に問題がない限り、または郵便配達員が何かを明らかにするように彼を説得できる場合を除き、彼のメッセージはジョージに安全に届くはずです。
それが私が目指していたものです。 GPG、またはFuseなどのユーザーランドベースのファイルシステムを使用する場合でも(完全に可能)、それらのキーを作成して暗号化を行うシステムを信頼する必要があります。そうでなければ、あなたが望むことができる最高のものは傍受するのがかなり難しいです。公開キー暗号化と対称暗号化を組み合わせて使用することはできますが、アクセス制御はシステムに物理的にアクセスできるユーザーと比較して価値がないため、ディスク暗号化でさえ、あなたが思っていることを達成していません。これを使用する唯一の理由は、ハードディスクをチャックしてから6か月後にハードディスクのフォレンジック分析を行うことが困難になるためです。
暗号化は、キーとデータが分離している場合にのみ機能します。とても簡単です。そのため、インターネット全体でTLSは機能します(攻撃者がキーを持っていないため)が、ローカルで暗号化を行うと、ある時点でシステムにアクセスするキーが機能しなくなります。したがって、必ず暗号化されたファイルシステムを実装し、それを暗号化するために使用された鍵を非対称鍵で保護してください。これは、このようなスキームで取得できる最も安全な方法ですが、次のようになります。
書き込み専用のファイルシステムは暗号的にも実行可能ですが、たとえば GnuPG ですでに実行できる機能に比べて、追加の機能はほとんどありません。
必要なものを正確に定義するには、ある程度の努力が必要です。多くの行動オプションがあります:
システムをカーネル駆動のファイルシステムとして持つことは、ファイルの通常のAPI(open()
、write()
...)を介してファイルを書きたい場合にのみ意味があります。次に、上記の質問に対する回答を制限します。 「通常のAPI」のサポートは、特定の自動暗号化ファイルシステムを認識していないアプリケーションのためにあります。一方、そのようなディレクトリにファイルを配置したいユーザーが特定のコマンドを呼び出さなければならない場合があることを受け入れると、カーネルに機能を実装する理由がほとんどなくなります。純粋にユーザー空間のソリューションも同様にうまく機能します。ユーザーランドプログラミングはカーネルプログラミングよりも制約が少ないため、おそらくより良いでしょう。 GnuPGでは、既存のユーザーランドソリューションがすでに存在し、「電子メール」と呼ばれています。
また、根があなたの敵であるならば、あなたは運命づけられています。ルートはUnixシステムでは万能です。彼は、必要に応じてカーネルを変更し、キーロガーをアクティブにするか、ファイルに書き込まれるすべてのバイトのコピーを取得することができます。一方、rootが敵ではない場合、システムの通常の非暗号化セキュリティ機能(ファイルアクセス権など)で十分です。データの機密保持を実施するため。そのための他の応答を参照してください。
暗号化あり。ファイルシステムの権限に依存したくない場合は、公開鍵暗号化を使用してこの問題を簡単に解決できます。
詳細これがその方法です。これらすべてのメッセージの受信者であるRadiaは、GPGを使用して公開鍵のキーペアを作成できます。次に、Radiaは公開鍵をすべてのユーザーに伝達する必要があります。たとえば、公開鍵をすべてのユーザーが読み取り可能な読み取り専用ファイルに保存する場合があります。 Radiaは、自分だけが読み取ることができるファイルに秘密鍵を安全に保存する必要があります。
メッセージを送信するために、アリスはRadiaの公開キーをGPGキーファイルにインポートし、GPGを使用してメッセージをRadiaの公開キーに暗号化し、暗号化されたファイルをRadiaに送信できます。暗号化されたファイルがどのようにRadiaに到達するかは、実際には重要ではありません。クリアテキストの電子メールで送信されたり、誰でも書き込み可能なディレクトリに保存されたり、その他の安全でない媒体で送信されたりする可能性があります。
メッセージを受信するために、RadiaはGPGを使用してメッセージを復号化できます(Radiaの秘密鍵を使用)。
Radiaのみがメッセージを復号化できます。ボブはRadiaの公開鍵を知らないため、ボブが暗号化されたファイルを傍受したとしても、ボブはアリスが送信しようとしたメッセージを読み取ることができません。
ディスカッション。これはすべて、公開鍵暗号の完全に単純なアプリケーションです。公開鍵暗号を自分で実装するのではなく、時間をかけて十分に検証された既存のファイル暗号化ソフトウェアを使用することをお勧めします。 GPGは、この目的のために強く推奨されています。代金を支払いたい場合は、PGPの商用製品を使用することもできます。 S/MIMEで暗号化された電子メールも、完全に妥当な実装です。このソリューションでは、ファイルシステムからの特別なサポートは必要ありません。代わりに、セキュリティはアプリケーション層で実装されます。
警告ルートはすべてのファイルを読み取り、すべてのメッセージを読み取ることができます。あなたはこれを望まないと言った。しかし、あなたが望むものは達成できません。既存のオペレーティングシステムでは、rootが悪意のあるものである場合、rootはすべてのユーザーが行うことをすべてスパイできます。 (「システムがキーロガーに対して安全であると仮定しましょう」とおっしゃいましたが、rootがキーロギングを行おうとしている場合、それを行う方法はありません。)したがって、これは達成可能な範囲で目標を達成します。
暗号化なし。 Unixファイルシステムでこれを行うには、標準のUnixファイルアクセス権を使用するだけで、暗号化の必要はありません。
詳細これがその方法です。まず、受信者(Radiaと呼ぶことにします)は次のように設定する必要があります。
radia $ mkdir /securefolder
radia $ chmod a+w,og-r,a+x,o+t /securefolder
radia $ ls -ld /securefolder
drwx-wx-wt. 2 radia radia 4096 Aug 13 18:34 /securefolder
これで、アリスはそこにファイルを書き込むことができ、Radia(および自分)だけが読み取ることができます。
alice $ umask 077
alice $ echo 'hello, Radia!' > /securefolder/hi_there
この時点で、RadiaはAliceが作成したファイルを読み取ることができます。
radia $ ls -l /securefolder
total 4
-rw-------. 1 alice alice 13 Aug 13 18:38 hi_there
# cat /securefolder/hi_there
hello, Radia!
しかし、ボブはアリスが作成したファイルを読み取ることも、自分のファイルを削除することも、そのディレクトリ内のすべてのファイルをリストすることもできません。
bob $ cat /securefolder/hi_there
cat: /securefolder/hi_there: Permission denied
bob $ rm /securefolder/hi_there
rm: cannot remove `/securefolder/hi_there': Operation not permitted
bob $ ls -l /securefolder
ls: cannot open directory /securefolder: Permission denied
(トリビア:ファイル名を推測したボブcanは、その名前のファイルが存在するかどうかをテストしますが、その内容を知ることはできません。ファイル名の機密情報をエンコードしない限り、実際には無害です。)
警告ルートはすべてのファイルを読み取り、すべてのメッセージを読み取ることができます。あなたはこれを望まないと言った。しかし、あなたが望むものは達成できません。既存のオペレーティングシステムでは、rootが悪意のあるものである場合、rootはすべてのユーザーが行うことをすべてスパイできます。 (「システムがキーロガーに対して安全であると仮定しましょう」とおっしゃいましたが、rootがキーロギングを行おうとしている場合、それを行う方法はありません。)したがって、これは達成可能な範囲で目標を達成します。
誰かがそのことだけを実装しました(これは私が必要としているものとはちょっと反対です...)
WOCFSは、書き込み専用の暗号ロックFuseベースのファイルシステムです。 Fuseマウントに書き込むことはできますが、そこに書き込まれたファイルは、別のツールなしでは読み取ることができません。十分な権限を持つ人はファイルを削除または移動できますが、ツールがないと、ファイルの読み取り/編集はできません。
それは使用可能ですが、RSA公開鍵暗号化を使用してエンコードしているため、速度の面でバーナーになることはありません。 libsodiumを使用するように作り直して、劇的にスピードアップできるかもしれません。
Rootがファイルの内容を実際に読み込めないようにするための唯一の方法は、自分のシステムでローカルにファイルを暗号化し、暗号化したバージョンを想定したシステムにアップロードし、それらを読む必要がある人にダウンロードを許可することです。それらをローカルで復号化します。この方法では、このサードパーティのルートがアクセスできるシステムにキーが存在しないため、ファイルの読み取りの問題は、選択した暗号化アルゴリズムを解読することの1つになります。アルゴリズムが安全であり、キーが十分に長い/複雑であると仮定すると、これは、実行に時間がかかりすぎるブルートフォース攻撃であることを意味します。
そのようなファイルシステムはないと思います。私が知っているのはMicrosoft EFS(NTFSで実装されている)だけです。非対称暗号を使用しているので、希望どおりに構成できる可能性があります。そのような構成はYMMVで試したことはありません。
最も簡単で互換性のある方法は、OpenPGPまたはS/MIMEのいずれかの電子メールを使用することです。ほとんどの電子メールクライアントは、受信者の公開キーを使用して送信メッセージを暗号化し、送信者キーを使用してローカルコピーを暗号化します。これにより、両方のクライアントが読み取り可能なコピーのみを持ちます(もちろん、秘密キーが秘密である限り)。
これは別の質問と似ています: https://serverfault.com/questions/89126
システム管理者が特定のサーバーログを一方向で暗号化する必要がある場合。そこに述べられているように、そのプロジェクトの警告を読んでください、しかしそこに述べられているのとは異なり、ここに説明されている使用シナリオのクイックスタートがあります。
ファイルを暗号化するユーザーアカウントにログインします。
ファイル「所有者」の公開鍵をインポートし、Var_gpg_id
変数の次のコマンドでそれらに関連付けられた電子メールを使用します。
Var_gpg_id='[email protected]'
Var_script_ower="${USER}"
Var_script_group="${USER}"
Var_gpg_file_ower="${USER}"
Var_gpg_file_group="${USER}"
Var_output_file="${HOME}/.secrets/gpg_messages.gpg"
Var_output_dir="${HOME}/.secrets/gpg_messages.gpg"
Var_named_pipe_location="${HOME}/Share/encryption_wormhole.pipe"
Var_script_copy_location="${HOME}/.secrets/wormhole_${USER}_pipe_listener.sh"
git clone https://github.com/S0AndS0/Perinoid_Pipes
cd Perinoid_Pipes
Perinoid_Pipes.sh -h
--help
を使用してスクリプトを実行し、設定を確認しますPerinoid_Pipes --copy-save-yn='yes'\
--copy-save-name="${Var_script_copy_location}"\
--copy-save-ownership="${Var_script_ower}:${Var_script_group}"\
--copy-save-permissions='100'\
--debug-level='6'\
--listener-quit-string='sOmErAnDoM_sTrInG_wItHoUt_SpAcEs_tHaT_iS_nOt_NoRmAlY_rEaD'\
--log-level='0'\
--named-pipe-name="${Var_named_pipe_location}"\
--named-pipe-ownership="${Var_gpg_file_ower}:${Var_gpg_file_group}"'\
--named-pipe-permissions='420'\
--output-bulk-dir="${Var_output_file}"\
--output-parse-name="${Var_output_file}"\
--output-parse-recipient="${Var_gpg_id}"\
--output-rotate-actions='compress-encrypt,remove-old'\
--output-rotate-check-requency='2500000'\
--output-rotate-max-bites='8388608'\
--output-rotate-recipient="${Var_gpg_id}"\
--output-rotate-yn='no'\
--output-save-yn='yes'\
--disown-yn='yes' --help
ユーザーのニーズに合わせて上記を調整し、スクリプトのコピーを書き込む準備ができたら--help
を削除してから、.bashrc
ファイルに次のようなものを追加します。
cat >> ${HOME}/.bashrc <<EOF
if [ -e "${Var_script_copy_location}" ]; then
if ! [ -p "${Var_named_pipe_location}" ]; then
echo "# Starting ${Var_script_copy_location}"
${Var_script_copy_location} || echo "## Failed!"
else
echo "# Detected [${Var_script_copy_location}] already running"
echo "# ${USER} may write to [${Var_named_pipe_location}] for auto encryption."
if
else
echo "## Could not start ${Var_script_copy_location}"
fi
EOF
最終的には、このユーザーでログインすると、bash起動ファイルが読み取られ、名前付きパイプファイルのステータスが確認されます。存在しない場合は、スクリプトコピーが実行されて再作成されます。既知のファイルまたはディレクトリパスが名前付きパイプ(echo "${HOME}/Downloads" > ${Var_named_pipe_location}
)に書き込まれると、スクリプトコピーは圧縮され暗号化された結果を${Var_output_dir}
で指定されたディレクトリに保存する必要があります変数。また、名前付きパイプに書き込まれたメッセージまたはランダムデータは、${Var_output_file}
変数で指定されたファイルに追加されます。
--named-pipe-permissions='420'\
オプションを422
に設定することをお勧めしますが、誰でもこのようなシステムエントロピーをプルできるようにすると危険な場合があるため、最初に表示されたより制限の厳しい権限で試してください。 。