PHPとJavaでSHA256の結果を同じにする方法

このQ&Aのポイント
  • PHPから JavaServletにアクセスするシステムを作っています。ハッシュ化する際の秘密鍵の違いが原因で、PHPとJavaでSHA-256でハッシュ化した値が異なってしまいます。Javaで内部的に使っている秘密鍵を取得する方法はありますか?
  • PHPとJavaで同じハッシュが取得できるようにする方法を教えてください。ハッシュ化する際の秘密鍵の違いが原因で、PHPとJavaでSHA-256でハッシュ化した値が異なってしまいます。
  • PHPとJavaで同じ結果のSHA-256ハッシュを取得したいです。PHPではハッシュ化する際に秘密鍵を指定できますが、Javaで同様の秘密鍵を指定する方法はありますか?
回答を見る
  • ベストアンサー

PHPとJavaでSHA256の結果を同じにしたい

PHPから JavaServletにアクセスするシステムを作っています。 その際にパラメーターの改ざん対策にハッシュを渡すようにしたいのですが PHPでSHA-256でハッシュ化した値と JavaでSHA-256でハッシュかした値が異なってしまいます。 PHPだとハッシュ化する際の秘密鍵を指定する項目がありますが Javaでは見つかりませんでしたので この項目が違うために結果が違うのだと予想していますが Javaが内部的に使っている秘密鍵はどこか取得できるのでしょうか? やりたいこととしてはPHPとJavaで同じハッシュが取得できるようにしたいのですが 良い案とかやり方あったら教えてください。 ◆php string hash_hmac ( string $algo , string $data , string $key [, bool $raw_output = false ] ) ◆Java DigestUtils.sha256Hex(string data) わかる方いましたら教えてください。よろしくお願いいたします。

  • Java
  • 回答数3
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

SHA256の値が言語で違うというのはかなりおかしいことだと思いますが... SHA256の計算方法は仕様として決まっており、言語やOSなどにかかわらず同じ入力に対して同じ結果が出ます。次のテストベクトル通りの答えが出ないとしたら、それが壊れてます。 http://www.nsrl.nist.gov/testdata/ > ◆php > string hash_hmac ( string $algo , string $data , string $key [, bool $raw_output = false ] ) 節子、それハッシュ値の計算やない。HMAC値の計算や。 ハッシュ値の計算をするのはこっち。 http://www.php.net/manual/ja/function.hash.php hash_hmacはHMAC値の計算に使います。 http://www.php.net/manual/ja/function.hash-hmac.php http://ja.wikipedia.org/wiki/HMAC MD5だと同じ結果が出るというのもかなり不思議ですが、偶然でしょうか? ちなみに、"abc"のSHA256を計算したらどうなりますか? 前述のNISTのページによれば、次が出てこないとダメなんですが。 "BA7816BF 8F01CFEA 414140DE 5DAE2223 B00361A3 96177A9C B410FF61 F20015AD" 改竄防止となると、もしかしてHMAC値の計算をしたかったのかもしれませんが、そうだとしたらこのテストベクトルを参照してください。 http://tools.ietf.org/html/rfc4231 前述のとおり、この結果を出さないほうが壊れてます。 なお、JavaでHMAC値を計算する方法は検索すればいくらでもサンプルコードが見つかると思います。DigestUtilsを使うとしたら、wikipediaに載っているようなHMACの計算を自分でやる必要があります。テストベクトル通りの答えが出ないのは間違いです。

yukitakao
質問者

お礼

PHPでhashを使ったらうまくいきました。 ありがとうございました。

その他の回答 (2)

  • amino_pl
  • ベストアンサー率50% (1/2)
回答No.3

No.2さんの通りだと僕も思います。 僕も"abc"で試しました。 System.out.println("SHA-256 = " + DigestUtils.sha256Hex("abc")); 結果は、 SHA-256 = ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad です。 ちなみに僕の環境です。 ・WindowsXP Pro 32bit ・javaバージョン:1.7.0_45 ・commons-codec-1.8.jar

  • amino_pl
  • ベストアンサー率50% (1/2)
回答No.1
yukitakao
質問者

お礼

回答ありがとうございます。 ただ残念ながらアスキー文字もうまくいかないのでリンク先の件とは別物のようです。 なおMD5はPHPとJavaでどちらも同じ値になりました。 SHA-256じゃなくてMD5使う方向で話を持って行くしかないか、、、とも思いつつ 相手方の現在のシステム(Java)がSHA-256使ってるので変えるの結構大変そうだしなぁ。。。

関連するQ&A

  • PHPのSHA256変換について

    C#で以下のロジックがあるのですが、 using System.Text; using System.Security.Cryptography; private static string getHash(string data, string salt, int stretchingcount, Encoding encode) {     int m = salt.Length / 2;     string tmp = salt.Substring(0, m) + data + salt.Substring(m);     byte[] buf = encode.GetBytes(tmp);     SHA256CryptoServiceProvider algorithm = new SHA256CryptoServiceProvider();     for (int i = 0; i < stretchingcount; ++i)     {         buf = algorithm.ComputeHash(buf);     }     return BitConverter.ToString(buf).Replace("-", string.Empty); } こちらのソースをPHPで同じ結果になるように実装したいのですが、 同じ結果にならず、困っています。 PHP側のソースは以下の通りです。 public static function funcPrivacyCheck($data,$salt,$stretchingcount){ $m = strlen($salt) / 2; $tmp = substr($salt,0,$m).$id.substr($salt,$m); $tmp = base64_encode(utf8_encode($tmp)); $hash = ''; for ($i = 0; $i < $stretchingcount; $i++) { if($hash <> ''){ $hash = hash_hmac('sha256' ,$hash, false); }else{ $hash = hash_hmac('sha256' ,$tmp, false); } } return $hash; } エンコードは、UTF-8を指定することが前提です。 ご教授頂きますようよろしくお願いいたします。

    • ベストアンサー
    • PHP
  • PHPとObjective-Cでハッシュが違う結果

    Objective-Cでハッシュ値を生成し、PHPに送って、 PHP側でもハッシュ値を生成し、この2つを比較したいと思っています。 PHPでは、以下の関数でSHA256が取得できることがわかりました。 hash_hmac('sha256', $text, false) Objective-Cは自分で実装する必要があるようなので、以下のページのコードを使わせてもらいました。 http://zak-za-k.blogspot.jp/2011/09/objective-csha256.html この2つの関数それぞれで、同じ文字列を使ってSHA256のハッシュ値を出したのですが、 結果が違ってしまいます。 2つの関数で同じ結果を得られるようにするにはどうすればよいでしょうか。 参考にした上記URLのコードの内容は、ほとんど理解できていません。 よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • Perlモジュールを使わずにsha256変換を使う方法

    下記のPHPと同じ結果をPerlで出したいです。 ■PHPデータ <?php // HMAC-SHA256 $hash = hash_hmac('sha256', hogedata, hogekey, 'true'); // BASE64エンコード print base64_encode($hash); ?> 検索エンジンで調べたところ、 「Digest::SHA256」などのPerlモジュールを使用すれば可能なようですが、 新しいPerlモジュールをインストールする権限のないため、 直接、Perlに式を記述したいと思いました。 ■Perlデータ(途中) #!/usr/bin/perl use MIME::Base64; print "Content-type: text/html\n\n"; # HMAC-SHA256 ~ここに変換式が入ります~ # BASE64エンコード $enhash = encode_base64($hash); print "$enhash"; PHPで書き直せば同じサイトを作ることは可能ですが、 できればPerlのままで継続したいです。 お分かりの方がいらっしゃいましたら、 ご教授いただけますでしょうか。 どうぞよろしくお願いいたします。

    • ベストアンサー
    • Perl
  • HMAC-SHA1ハッシュ関数について

    HMAC-SHA1ハッシュ関数について質問です。 HMAC-SHA1 によってダイジェスト値を生成し、BASE64 でエンコードすることによってシグニチャを生成したいと考えました。 参考サイト http://weboo-returns.com/blog/php-oauth-consumer-request-2-legged-oauth/ 上記の例では、 ●ダイジェスト値 GET&http%3A%2F%2Fapi.gu3.jp%2Fv1%2Ftest%2Fauth&oauth_consumer_key%3Dyamashita.dyndns.org%26oauth_nonce%3Dc83b1847200bd25d918c3fb077aca16f%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1219931263%26oauth_version%3D1.0 ●共有キー kd94hf93k423kf44& とした場合、ここから得られる、シグニチャは以下のようになりますと書かれています。 M32qYtcaUD8b1Kb/AponRG5hrwI= 上記を下記のPHPで試してみました。 ********************************************* <?php $key2 = 'kd94hf93k423kf44&'; $Base_String2 = 'GET&http%3A%2F%2Fapi.gu3.jp%2Fv1%2Ftest%2Fauth&oauth_consumer_key%3Dyamashita.dyndns.org%26oauth_nonce%3Dc83b1847200bd25d918c3fb077aca16f%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1219931263%26oauth_version%3D1.0'; $OAuthSignature2 = base64_encode(hash_hmac('sha1', $Base_String2, $key2, true)); echo $OAuthSignature2."\n"; ?> ************************************** ここから得られたシグニチャは以下のようになりました。 /j6JriS6FRFbKat4X3pJg4hO1Po= 残念ながら例示であるM32qYtcaUD8b1Kb/AponRG5hrwI=と一致しません。 私のPHPの書き方に誤りがあるようです。 質問 HMAC-SHA1 によってダイジェスト値を生成し、BASE64 でエンコードすることによってシグニチャを生成するPHPはどのように書けばよいのでしょうか?

    • ベストアンサー
    • PHP
  • Access2000のVBAでSHA-256ハッシュ値を計算

    Access2000のVBA上で任意の値からSHA-256ハッシュ値を計算したいと考えています。 VB.netやPHPなど、他言語でのハッシュ値計算方法はWeb上でも探すことができたのですが Access2000のVBA上で行う方法が分かりません。 何とかしてハッシュ値を簡単に求める方法はないでしょうか。よろしくお願いいたします。

  • PHPのpack関数をJavaで実装できるのでしょうか

    PHPで文字列を16進バイナリ文字列に変換する関数であるpack関数というものがありますが、これと全く同じ動きをしてくれるメソッドがjavaには存在しないようです。これを自分で実装する方法をあれこれ考えているのですが、どうしてもうまくいきません。 下のようなメソッドを作ってみたのですが、戻ってくるのはただの数値文字列です。 /** * @param toPack バイナリへの変換対象の数値 */ String getHexBinary(int toPack){ String buf = ""; String hex = Integer.toString(toPack, 16); char decChars[] = hex.toCharArray(); for(int decChar : decChars){ buf += Integer.toHexString(decChar); } return buf; } PHPのpack関数はこの戻ってくる数値文字列を何らかの手法で結合しているように見えるのですが、その挙動が理解できずに困っています。どなたか、ご教授願えないでしょうか。ちなみに、Javaのバージョンは5.0でやっています。PHPのバージョンは5.2です。

    • ベストアンサー
    • Java
  • Map<String, String> Hash = new Hash

    Map<String, String> Hash = new HashMap<String, String>(); このjavaのハッシュマップの初期化の方法を教えてください。

    • ベストアンサー
    • Java
  • サーバ証明書等の正当性の確認について。

    サーバ証明書、証明書には、 認証局の署名をSHA-1等のハッシュ関数で、 ハッシュ化されたハッシュ値を、 認証局の秘密鍵で暗号化された認証局の電子署名が付加されていると思いますが、 その部分の信頼性についてですが、 認証局から、 公開鍵を取り寄せて、 ハッシュ値を取り出すと思うのですが、 もともとの平文(署名)を認証局から取り寄せることは可能でしょうか。 認証局の公開鍵で復号できたから、 認証局の秘密鍵で暗号化されているといえるのですが、 もともとの署名が何かがわかりません。 (ちょっと信頼性にかけるような気がします。) 署名を取り寄せることができれば、 署名をSHA-1等を使って、 ハッシュ値を取り出して、 公開鍵で復号したハッシュ値と比較することができます。 公開鍵と平文(署名)を取り寄せることはできないのでしょうか。

  • ハッシュ化で元の文字列の方が長くても大丈夫ですか?

    例えば1000桁の文字列をphpのhash()でsha512を用いてハッシュ化した場合、重複の危険性は 無視出来る程度なのでしょうか。 ご存知のかた、お手数をおかけいたしますがご回答のほどよろしくお願い致します。

  • ハッシュを使った擬似乱数

    予測不能な擬似乱数列を生成する際に、よく一方向ハッシュの性質を利用する 場合があります。一方向ハッシュの生成源として内部状態が与えられますが、 内部状態のbitサイズはどの程度にしたらよいでしょうか?   [種(カウンタの初期値)]        |        |        ↓ ┌→[内部状態(カウンタ)]―┬―→(一方向ハッシュ)――→擬似乱数列 |                 | |                 ↓ |               [1増加] |                 | └―――――――――――┘ ※ 暗号技術入門 秘密の国のアリス 結城 浩 著      ――第12章 乱数 Fig.12.5 より 極端な例として鍵(種)のサイズを32bit(C言語でunsigned long型)、値を0とします。 |0000 0000|0000 0000|0000 0000|0000 0000| 上記の値でハッシュ値を取ります。ハッシュアルゴリズムがSHA1の場合、 以下のような値が得られます(と思います)。 a = -1099956234 b = -343932961 c = -1287651379 d = -84150665 e = -1099170433 これらの値から鍵の値を得ることは困難なので、ハッシュ値によって生成された 擬似乱数は予測不能であるといえます。また、鍵の値を1だけ加算させて次の擬似乱数 を生成します。一般的にこのようにして乱数列は生成されます。 上記の例では32bitのとり得る値は0~4294967295です。鍵の値を一つずつ試し ていけば、それほど時間をかけることなく乱数の予測不能性は破られてしまいます。 ここで鍵の値を256bitとしました。 |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| しかしこれだと1加算しただけではビット全体に対して変化が少なすぎます。 |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0001|← 2005年に中国の大学の研究チームによってSHA1の弱衝突耐性が破られてしまいました。 現段階ではSHA1に変わる新しいアルゴリズムは発見されていません。(SHA2が作られましたが、 これはSHA1のbit数を拡張しただけで基本設計は変わっていません)なのでハッシュ値を 生成させる値もなるべく変化に富んだ値を与えることが推奨されています。 まとめると、   ・鍵(種)を総当り攻撃されないようにbit数を大きくしなけらばならない。   ・bit数を大きくすると1加算したときに変化が小さすぎる。   ・最初の図の手法は同記の文献に書いてあったもので、なるべく変えたくない。    (実際に使われる手法はある程度保障されているから) の制約があります。なので”bit数をどの程度にしたら適当か???”というのが質問です。 また、これらの問題を打開する方法もあればよいのですが、、、

専門家に質問してみよう