画像を暗号化形式で保存する必要があるプロジェクトを準備しています。画像は 0.5mb から 5mb の間で、元の品質を維持する必要があります。
base64 を使用してエンコードすることを考えていましたが、何かを使用して暗号化し (SHA1?)、サーバーにファイルとして保存する必要があります。
誰でもこれについて私にアドバイスできますか?暗号化された画像はどのようなファイルに保存できますか?
前もって感謝します
画像を暗号化形式で保存する必要があるプロジェクトを準備しています。画像は 0.5mb から 5mb の間で、元の品質を維持する必要があります。
base64 を使用してエンコードすることを考えていましたが、何かを使用して暗号化し (SHA1?)、サーバーにファイルとして保存する必要があります。
誰でもこれについて私にアドバイスできますか?暗号化された画像はどのようなファイルに保存できますか?
前もって感謝します
操作は簡単ではありません。データを暗号化するだけでなく、盗難やサーバーへの侵入に対して安全にする必要があります。また、キーを変更する必要がある場合にどうなるかを考慮する必要があります。
画像を暗号化するには、おそらく対称アルゴリズムを使用したmcryptが最適です。その方法については、いくつかのチュートリアルがあります。PHP を使用して AES-256 でファイルを暗号化する最良の方法は何ですか? を参照してください。.
必要なのは、画像を平文で保存せずに、その場で提供して復号化することです。
問題は、パスワードをどこに保管するかです。全体的な最善の解決策は、ユーザーの登録時にランダムに生成された、すべてのユーザーに秘密の暗号化キーを用意することです。キー自体は、ユーザーのパスワードと非対称に暗号化されます。phpseclib
RSAでそれを行うために使用できます。同じ暗号化キーも、管理パスワードとは非対称に保存されます。
したがって、ワークフローは次のとおりです。
画像を暗号化するには: - ユーザーが画像をアップロードすると、アップロード時に暗号化キーがセッションで使用可能になります。それを使用してください :-) - 画像が他の方法でアップロードされた場合、データベースに「暗号化済み/まだ暗号化中」フラグが設定され、できるだけ早く (管理者ログイン/ユーザー ログイン) 保留中のすべての暗号化が行われます。操作が実行されます。
画像は暗号化されたファイル (「001823040.bin」) として保存されます。データベースを除いて、どのユーザーに属しているかについての参照はありません。ユーザー (したがって暗号化キー) がわからないため、イメージは回復できません。
画像を提供するには、ヘッダーを画像タイプに設定し、ファイルのデコードを開始して、ユーザーのブラウザーに平文で出力します。
攻撃者の観点からは、画像は暗号化されているため、単独で使用しても意味がありません。暗号化キー自体が暗号化されているため、ユーザー データベースは役に立ちません。あるユーザーのパスワードを盗んだりブルートフォースしたりしても、そのユーザーの暗号化キーへのアクセスしか得られません。これは他のすべてのユーザーとは異なります。そのユーザーに属する画像を見つけるタスクはまだあります。
ユーザーのパスワードを変更する必要がある場合でも、管理パスワードを使用して暗号化キーを回復し、ユーザーの新しいパスワードで非対称的に再暗号化できます。これは、今や非常に重要な管理者パスワードをシステムに平文で保存することを意味するため、自動的に行うことはできません。そのため、パスワードを忘れたすべてのユーザーが一斉に整列し、朝、管理者は「パスワードの復元を待っている人が 75 人います」という通知を受け取り、パスワードを提供し、すべてのロックを解除します。
厄介なことですが、残念ながら、他のすべてのソリューションは、パスワードがプレーンテキストでローカルに利用できることに依存しています。
(この制限を回避するには、暗号化エスクロー サービスとして機能する、小規模で非常に制限された、したがって脆弱ではない2 番目のサーバーをセットアップすることで回避できますが、維持するのははるかに複雑です)。
1 つのテーブルにリソース A があり、そのリソースにアクセスできる複数のユーザー U1、U2、... Un があります。つまり、ユーザー U1 はリソース A の復号化キーにアクセスできる必要があります。
これは、UserAccessToResource テーブルを格納することで実行できます。
user_id -- the user ID
resource_id -- the resource ID
encryption -- resource decryption key, encrypted with the user's encryption **key**
ユーザー U1 とリソース A にアクセス権を付与するには、リソース AとU1 の暗号化キーにアクセスできる必要があります。あれは:
ユーザー U5 がやって来て、UserAccessToResource テーブルに (5, 42, ??) が存在することをすぐに確認できるため、リソースにアクセスできることがわかります。行を取得し、ResourceKey を復号化します。これで、 Resource[42] にアクセスし、ResourceKey で復号化できます (ただし、別のランダムな ResourceKey を持つため、他のリソースは使用できません)。
このすべてにおいて、フロントエンドは ResourceKey (または UserKey) の実際の値に (プログラミング エラーを除いて) アクセスすることはありません。API は似たようなものDecryptResource(UserId, UserPass, ResourceId)
で、復号化されたリソースを返します。
もちろん、UserAccessToResource には任意の数のユーザーまたはリソースを含めることができます。多対多です。それぞれに対して、暗号化されたキーを保存する必要があります (たとえば、AES エントリの場合は 32 hex バイト)。
残念ながら、この操作を自動的に行うことはできません。ユーザーはリクエストを送信しますが、管理者がログインするまで、ユーザーのキーにはアクセスできません。したがって、管理者は待たなければなりません。
管理者がログインすると、システムは PasswordRecovery テーブルにアクセスして、ユーザーの不完全な記録を見つけることができます。ユーザー テーブルにアクセスし、UserKeyEncryptedWithAdminKey を取得します。
これで、ランダム キーが生成され、その 1 つのランダム キーを使用して暗号化された UserKey で PasswordRecovery テーブルのレコードが完成します。別の列には、同じランダムキーで暗号化された「Squeamish Ossifrage」という単語が含まれています。彼は安全な電子メールをユーザー 123 に送信し、ランダム キーを提供します。
ユーザー 123 はランダム キーをシステムに提供します。管理者はログインしていませんが、暗号化が解除されると、2 番目のテーブル フィールドが実際に「Squeamish Ossifrage」であることをシステムが確認できます。次に、最初のフィールドが復号化された UserKey であると想定します。システムは User123 に新しいパスワードを要求し、新しい UserKeyEncryptedWithUserPass を Users テーブルに格納して、PasswordRecovery からエントリをクリアします。1 つのレコードのみが更新されました。ユーザー 123 が所有するすべてのリソース キーは、ユーザー 123 のキーで暗号化されたままです。このキーは変更されておらず、管理者がアカウントを作成したときにランダムに生成されたままです。
次回のログイン時に、ユーザーはパスワードを入力してシステムのロックを解除します。
同様のタスクを実行し、アプリケーションにアップロードされたファイルを暗号化してサーバーに保存し、ユーザーがアプリケーションからそのファイルを要求したときに、ブラウザーに送信する前にそれらを復号化する必要がありました。
私のアプリケーションは特別な種類のデータ (家庭内暴力) を扱っていたため、私の国の法律では暗号化して保存する必要がありました。したがって、OPの状況は、技術的な理由ではなく、法律を遵守するために暗号化する必要があることを理解しています。
私がしたことは、サーバーにOpenSSLをインストールして、それを使用してファイルをAES-256暗号化できるようにすることでした。これを使用system()
して、phpからコマンドを実行できます。
暗号化するコマンドは次のとおりです。
echo MyPassword | openssl.exe aes-256-cbc -pass stdin -salt -in somefile.pdf -out somefile.pdf
および復号化の場合:
echo MyPassword | openssl.exe aes-256-cbc -pass stdin -d -in somefile.pdf -out decriptedfile.pdf
このコマンドは生のファイル(形式に関係なく)を受け取り、復号化するとまったく同じファイルが再作成されるため、base64エンコードなどの必要はありません。フィードしたものが返されます。
サーバーを移行する場合に考えられる警告については、Windows の openssl aes-256 暗号化ファイルを Linux で復号化できない を参照してください。
たとえば、この関数を使用して実際にそれを行うことができます: http://php.net/manual/en/function.openssl-encrypt.php