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

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

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

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

Q&A

4回答

10753閲覧

php暗号化時の一意性について

enigumalu

総合スコア192

PHP

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

0グッド

2クリップ

投稿2017/02/08 09:46

編集2017/02/09 01:48

php暗号化時の一意性について
phpのopenssl_encryptを利用した場合
暗号化する前の文字が一意を保たれていた場合、暗号化後も一意が保たれるでしょうか。(パスワードは固定です)

$iv = '1234567890123456'; var_dump(openssl_encrypt('1486601281','AES-256-CBC','aaatest',0,$iv)); var_dump(unpack("H*", openssl_encrypt('1486601281','AES-256-CBC','aaatest',0,$iv))); 結果 string(24) "V3zbf8fVlSc32J/+76vpNg==" array(1) { [1]=> string(48) "56337a62663866566c536333324a2f2b373676704e673d3d" }

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

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

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

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

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

ikedas

2017/02/08 10:35

自分で試してみましたか。試したコードとその結果を提示していただけませんか。
ockeghem

2017/02/08 12:12

初期化ベクトルはどうしていますか?
enigumalu

2017/02/09 01:04

すいません初期化ベクトルに関して考慮が抜けていましたが、固定文言を渡すようにしています
ikedas

2017/02/09 01:11

自分で試してみた結果を提示して下さいませんか。
guest

回答4

0

質問者さんの提示したコードでは暗号方式にAES-256-CBCが指定されていますから、暗号化のたびにランダムな初期化ベクタ (IV) を指定しなければなりません。ですから、平文が一意であっても暗号文は一意になりません。

以下、説明です。

  • 初期化ベクタ (IV) やソルトを使わない暗号方式では、平文と暗号文が一対一に対応します。ブロック暗号では、ECBモードの場合はIVを使いません。
    しかし、このような暗号方式はもはや用いるべきではありません

  • 初期化ベクタ (IV) やナンス (nonce) を使う暗号方式は、IVやナンスを暗号化の度に変えるという正しい運用をするかぎり、同じ平文が同じ暗号文になることはほぼありません。ブロック暗号では、ECB以外のモードではIVを用いる (CBC、CFB、OFB等) かナンスを用いる (CTR等) かです。
    そして、IVやナンスに固定した値を用いるべきではありません

IVを使わない暗号方式を使うことも、IVを固定して使うことも、するべきでない理由は同じです。そのようなものは、現在では十分な強度のある暗号方式とみなされていないからです。

「でも、IVを固定すれば一意になるんでしょう。ならそういう使いかたをしたっていいじゃないか」と思うかもしれません。しかし、暗号方式の設計で想定されている以外の運用をすれば、暗号化の強度は全く保証できなくなります。暗号化しているつもりで安心していると、すべて誰かに解読されてしまっているかもしれないのです。これほど危険なことはありません。


参考文献


ところで、質問者さんのやりたいことが何なのか、いまひとつわかりません。

一意な文字列を作りたいのであれば、規則的に変化するもの (連番など) でいいはずです。規則性のない文字列にしたいのであれば、乱数を使うしかありません。両立は無理です。

また、やりたいことがわからないので憶測ですが、文字列を予測困難にする――次に生成される文字列を隠す――必要があるのかどうかも、再考すべきなのかもしれません。

投稿2017/02/09 04:43

ikedas

総合スコア4333

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

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

0

復号できるデータは、暗号化する前のデータと一対一で結びつきます。

openssl_encrypt は復号可能な暗号アルゴリズムを使用するので、暗号化後の文字列は暗号化した文字列の中で一意のものとなります。

追記
別の場所で、初期化ベクトルのこと考えてないんじゃないの?と指摘を受けました。
確かに、初期化ベクトルが異なれば、暗号化後の文字列が被る可能性がありますね^^;
初期化ベクトルと暗号化後の文字列をセットとして考えた時、一意性が確保されます。と補完させていただきます。

投稿2017/02/08 09:53

編集2017/02/08 13:22
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

enigumalu

2017/02/09 01:03

初期化ベクトルivも固定値を渡すようにしています。 $iv = '1234567890123456'; var_dump(openssl_encrypt('1486601281','AES-256-CBC','aaatest',0,$iv)); var_dump(unpack("H*", openssl_encrypt('1486601281','AES-256-CBC','aaatest',0,$iv))); 記号をなくすために最終的にunpackしているのですがこれだとさすがに一意にはならないですよね
退会済みユーザー

退会済みユーザー

2017/02/09 04:52

ikedas さんも指摘していますが、何をやりたいのかよく分かりません。 そもそも何をやりたいのか分かれば、適切な解なり検討方法なりのアドバイスが貰えると思います。 もう一度整理されては?
guest

0

既に書かれていますが、復号可能である以上、元の平文と暗号文は1対1に対応します。複数の平文が同じ暗号文になることはありません。

ですが、そうすると、「同じ文面では同じ暗号文が出てくる」ので、特に先頭に定型文があると「あ、定型的な文章を送っているな」と類推されてしまう危険性があります。
※先頭のブロックが同一だと、暗号文も同一でスタートします

そこで初期化ベクトルという「先頭にランダムな1ブロックを加える」ことにより、「同じ文面でも異なる暗号文を出す」ようになっているわけです。
※ゆえに初期化ベクトルのサイズは暗号化時のブロックサイズと一致していなければならない
このため復号時には暗号化で使用した初期化ベクトルも知っている必要があります。

平文(あるいは暗号文)と初期化ベクトルの組が一意であれば、暗号化もしくは復号した結果も一意になります。

投稿2017/02/09 02:10

tacsheaven

総合スコア13703

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

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

0

質問の意図(やりたいこと)がうまく捉えられているか分かりませんが

  • 相異なる平文から1対1で対応する(=相異なる)ランダムに見える値を得たい。
  • 変換後の値から平文に戻す必要はない。

ならハッシュを使えばよいのでは?
ハッシュ関数によっては1対1にならない可能性もありますが(詳しくは「衝突耐性」で調べてください)

また、以下は自分の疑問に対する覚書なので無視してくださって結構です。

問:暗号時にIVをランダムで生成した場合、復号側ではIVはどうやって知るのか?

答(opensslでの実装)
・ソルト+暗号データを渡す。ソルトは単なるランダム値なので見えてもよい。
・(暗号鍵と)IVはパスワードとソルトからハッシュで生成する。

salt = 暗号側でランダム生成。復号側は受け取って利用する。 暗号鍵 = MD5(password + salt) IV = MD5(暗号鍵 + password + salt)

参考:Opensslの暗号鍵とIVの生成アルゴリズム

投稿2017/02/09 06:02

can110

総合スコア38262

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問