質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

暗号化

ネットワークを通じてデジタルデータをやり取りする際に、第三者に解読されることのないよう、アルゴリズムを用いてデータを変換すること。

Q&A

解決済

5回答

4749閲覧

利用ユーザしか復号化できない暗号化処理

kensii

総合スコア191

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

暗号化

ネットワークを通じてデジタルデータをやり取りする際に、第三者に解読されることのないよう、アルゴリズムを用いてデータを変換すること。

0グッド

2クリップ

投稿2016/12/27 12:30

###前提・実現したいこと
PHP(CakePHP2.x)でログインを必要とするWebアプリケーションを作成しています。
MySqlにデータを保存する際、暗号化して保存→取り出す時は文字列を複合化して表示させるようにしたのですが、
これだと、最悪の場合システム管理者(復号化キーを知る者)が悪意を持ってしまったら、DB
からデータを抜き取って複合化出来てしまうと思いました。

DBを抜き取られてもアプリケーションの管理側すら復号化できない様にすることなどは可能なのでしょうか。

恥ずかしながら方法論がなかなか見つけ出せません。
ご存知の方いらっしゃいますでしょうか。

###試したこと
・crypt系の関数を使い、復号化キーを持たせて、DBに保存してある暗号化文字列を復号化
・復号化キーはアプリケーション全体で一つを定数化している

PHP

1// 復号化のために必要なキー 2define('CRYPT_KEY' ,'hogehoge'); 3 4$text = '保存したい情報'; 5 6// 暗号化(DBへの保存時) 7$encrypted_string_for_db_save = openssl_encrypt($text,'aes-256-ecb',CRYPT_KEY); 8 9// 復号化(DBからデータを取り出したとき) 10$decrypted_string = openssl_decrypt($encrypted_string_for_db_save ,'aes-256-ecb',CRYPT_KEY); 11

###補足情報(言語/FW/ツール等のバージョンなど)
結局DBに情報が保存されてしまうので実現できてないのですが、各ユーザのハッシュ化されたログインパスワードを復号化キーにすべきかとも考えました。

PHP5.6.10

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

ベストアンサー

Passpackというパスワード管理サービスが利用ユーザーしか復号化できない仕組みを取っています。

仕組み的には次のような形であると(自称)しています。

  1. サービスにログインします。(これは通常の方法です。他サービスとのシングルサインオンにも対応しています)
  2. パッキングキー(packing key)を入力します。このキーはブラウザ上にのみ保存されており、サーバーには送られません。正しいかどうかは、サーバー側に正しいキーのみ複合化できる暗号化されたデータがあり、それをブラウザに送って、ブラウザ上で復号化していて確認しているようです。また、実際はパッキングキーそのものでは無く、パッキングキーをハッシュ化したものを秘密鍵として使います。
  3. パスワードを登録します。パスワードはJavaScriptを用いてブラウザ上で2.で保存された秘密鍵で暗号化します。暗号化済みのデータをサーバーに送ります。
  4. 登録したパスワードを複合化する場合は、サーバー側から暗号化されたデータを送って貰い、ブラウザ上で2.で保存された秘密鍵を使って復号化します。

パッキングキーを忘れた場合、サービス管理者でも復号化は不可能になります(実際は、変更前のパッキングキーで暗号化したデータを一回分のみサーバー側で保存しているため、変更直後のみ変更前のキーで復号化ができるようです)。クライアントサーバー間の通信には暗号化済みのデータしか送られず、サーバーには暗号化済みのデータしか保存されません。そのため、たとえSSL/TLSの未知の脆弱性を使って盗み見られても、サーバーをハッキングされてデータを全て盗まれても、暗号化の仕組みそのもの自体に脆弱性がなければ、生のデータを取ることは(現実的ではない時間を掛けない限り)不可能です。

このようにブラウザ上で暗号化・復号化を完結させる必要があります。PHPだけでは不可能であり、むしろ、**PHP側では暗号化・復号化の処理を行ってはいけません。**キーを毎回クライアントからサーバーへ送るという安易な方法が思いついたかもしれませんが、PHPを少し改造して、その送られてくるキーをログに出すようにするだけで、キーは入手し放題なるため、意味がありません。

具体的なJavaScriptについては私も知らないので何もアドバイスできないのですが、JavaScriptを用いた暗号化・復号化について、調べるといいかと思います。

投稿2016/12/27 22:16

raccy

総合スコア21733

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kensii

2016/12/28 05:42

なるほど。 ブラウザ側での実装をしないとだめみたいですね。 そうなるとこのPasspackのようにそれだけでサービスが出来上がってしまいそうですね汗 私にはハードルが高そうですがJSでの実装も調べてみます。 大変勉強になります。ありがとうございました。
guest

0

"元のデータを表示"が必要な時点でほぼ対処不可能。
そもそもpassword_hash()などの一方向関数を用いて元に戻せなくするべき。

なお、余計な実装は不要で、何も考えずにAuthComponentを使っておけば勝手にpassword_hash()されるから、
管理者を含め誰も元パスワードを知ることはできない。

http://book.cakephp.org/2.0/ja/core-libraries/components/authentication.html
http://book.cakephp.org/2.0/ja/tutorials-and-examples/blog-auth-example/auth.html

https://github.com/cakephp/cakephp/blob/df1b9b8aa75ece32dbe5e5343a249f3058ba1f3f/src/Auth/DefaultPasswordHasher.php

投稿2016/12/27 15:09

rana_kualu

総合スコア92

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/12/27 19:51

復号化が要件なので、それの否定ではなく、「ほぼ対処不可能」の対処できる箇所を回答してあげるべきだと思います。
guest

0

そもそも複合化できないようにすればいいかと。

Password Hashing 関数
http://php.net/manual/ja/ref.password.php

投稿2016/12/27 12:34

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/12/27 19:52

要件を取り違えていると思います。
退会済みユーザー

退会済みユーザー

2016/12/27 21:56

現実的な提案をしているだけですが?
maisumakun

2016/12/27 23:07

今回保存するデータは「パスワード」ではなく、「ユーザーに表示する文字列」なので、これでは使いようがありません。
退会済みユーザー

退会済みユーザー

2016/12/27 23:12

表面上の質問はそうですけどねぇ
退会済みユーザー

退会済みユーザー

2016/12/28 00:31

文句しか付かないので追記してみます。 利便性を残して誰にも複合化できないようにするには先に述べた通りの状況ですが、二つ目のパスワード(鍵)を発行する以外で考えると、不可逆パスをDBに保存して、ログイン時の入力を暗号化して時限式で別に持たせるとか、ソースは触れない前提ならいっそクッキーで鍵っとくとか。そんなオープンな環境じゃないなら物理媒体とか秘密鍵認証とか好きにやればいいと思いますが、新しい認証方式を考えるみたいな話でしたら私が場違いでした。
退会済みユーザー

退会済みユーザー

2016/12/28 01:07 編集

それで話は戻りますが、どんな無敵の暗号化しても最後に表示させるなら、管理者だったらパスワード抜けますよね。
guest

0

システム管理者(つまりサーバサイド)でもデータを読めないようにするなら、サーバへデータを送信するまえに、利用者のみ知る秘密鍵を使って暗号化して、それをテキスト化(base64等)してDBに保存すればいいです。

投稿2016/12/27 12:34

moonphase

総合スコア6621

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/12/27 22:54

横からの質問で恐縮ですが、そのような仕組みを作った場合、秘密鍵はどのように保管(?)するのが一般的なのでしょうか?
moonphase

2016/12/27 23:26

利用者側で管理します。
退会済みユーザー

退会済みユーザー

2016/12/27 23:34

あまり意味のない質問でしたね^^;失礼しました。回答ありがとうございます。
guest

0

暗号化すると情報を隠せると考えられているかもしれませんが、鍵を秘密にしないと暗号化は意味がありません。

利用ユーザしか復号化できない

特定の個人のみ復号化できればよいのであれば、鍵を個人に持たせ、

各ユーザのハッシュ化されたログインパスワードを復号化キーにすべきかとも考えました。

というような方法で秘密にすることは可能です。似た方法はたくさんありますが、個人が鍵を管理するという意味では同じです。一般的には、個人の情報を安全に保管していてもアプリケーションとして動作するときにはそれを外部に持ち出す必要があり、あまりうまくいきません。

これだと、最悪の場合システム管理者(復号化キーを知る者)が悪意を持ってしまったら、DB

からデータを抜き取って複合化出来てしまうと思いました。

この問題に対しては、複数人の鍵が揃わないと復号化できないという仕組みを備えたものもあります。たとえば、5人に鍵を配布し、そのうち3人の鍵が揃わないとサーバを起動できないというように構成することが可能です。ただし、サーバを起動する毎に5人中3人を集めて鍵を入力してもらう必要があります。

参考:Introduction to Vault

この Vault は鍵の保管庫であり、各サービスはここから鍵を読み出して動作します。このような仕組みを導入するというのも一つの手です。あらゆる管理者パスワード、暗号化鍵を Vault に入れて、サービスの起動時に動的にメモリに呼び出す仕組みであれば、ディスクには鍵が残りません。

投稿2016/12/27 12:48

mit0223

総合スコア3401

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kensii

2016/12/28 05:38

Vaultというものがあるのですね。しりませんでした。有用な情報ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問