読者です 読者をやめる 読者になる 読者になる

フリーランス兼主夫

技術系ブログ

ハッシュ関数で暗号化

java ruby php

データをサーバーに保管する際、データによっては暗号化した状態で保存し利用する、という要求は往々にして発生します。
この場合、
・逆変換されないこと(現実的にむり)
・変換が一意であること
が大事になります。
要はハッシュ関数使ってハッシュ化しようぜ、というお話。
これまでMD5SHA-1を使う場面がよくあったけれど、よくよく調べてみるとSHA-1には脆弱性があり、SHA-2を使いましょうということでした。

SHA-2はSHA-224/SHA-256/SHA-384/SHA-512の総称でいまのところ脆弱性は発見されていないとのこと。

PHPでSHA-256をつかう

PHPでSHA-2でハッシュ値を得るにはmhash()関数を使います。

<?php
$str = "string";
$hash = mhash(MHASH_SHA256, $str);
echo bin2hex($hash);
?>

mhashを利用するには、extraのmhashモジュールが有効になっていないといけません。phpinfo()で確認すると良いでしょう。mhashの欄がenableとなっていれば良いでしょう。
Windowsの場合は php.ini に追加(またはコメントアウト)しましょう。

extension=php_mhash.dll

Linux系(CentOS5)の場合はyumでインストールしてください。
まずインストールされているか確認しましょう。

# yum list | grep php
php.i386                                 5.1.6-20.el5_2.1       installed
php-apc.i386                             3.0.16-2.nt1           installed
php-cli.i386                             5.1.6-20.el5_2.1       installed
php-common.i386                          5.1.6-20.el5_2.1       installed
php-mbstring.i386                        5.1.6-20.el5_2.1       installed
php-mysql.i386                           5.1.6-20.el5_2.1       installed

〜中略〜

graphviz-php.i386                        2.12-8.el5             epel
mod_suphp.i386                           0.6.3-1.el5            epel
php.i386                                 5.1.6-24.el5_4.5       updates
php-IDNA_Convert.noarch                  0.6.3-2.el5            epel
php-PHPMailer.noarch                     5.0.2-3.el5            epel
php-mcrypt.i386                          5.1.6-15.el5.centos.1  extras
php-mhash.i386                           5.1.6-15.el5.centos.1  extras   <- mhashモジュール

"installed" となっていればインストール済みです。
"extras"となっているのでインストールされていませんので、インストールしましょう。

# yum install php-mhash

〜中略〜

=============================================================================
 Package                 Arch       Version          Repository        Size
=============================================================================
Installing:
 php-mhash               i386       5.1.6-15.el5.centos.1  extras            8.3 k

Transaction Summary
=============================================================================
Install      1 Package(s)
Update       0 Package(s)
Remove       0 Package(s)

Total download size: 8.3 k
Is this ok [y/N]: y
Downloading Packages:
(1/1): php-mhash-5.1.6-15 100% |=========================| 8.3 kB    00:00
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing: php-mhash                    ######################### [1/1]

Installed: php-mhash.i386 0:5.1.6-15.el5.centos.1
Complete!

これでインストール完了。

RubyでSHA-256をつかう

Digestライブラリが標準で同梱されているのでそれを使います。

require 'digest/sha2'
str = "string"
hash = Digest::SHA256.hexdigest(str)
p hash

かんたんですね。

JavaでSHA-256を使う

java.security.MessageDigestクラスを利用します。
JavaではStringのバイトコードを使用してハッシュ値をし取得しますが、最終的にdigest()メソッドで取得できるハッシュ値
byte[]型になるので、それを文字列で扱うには変換する必要があります。

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;


public class Encrypter {

	public static void main(String[] args) {
		
		String str = "string";
		System.out.println(sha256(str));
	}

	/**
	 * 入力された文字列のSHA-256ハッシュ値を得る。
	 *
	 * @param input 文字列
	 * @return	ハッシュ値
	 */
	public static String sha256(String input) {
		return hash(input, "SHA-256");
	}
	


	/**
	 * ハッシュ値を計算する。
	 *
	 * @param input		入力文字列
	 * @param algorithm	使用するハッシュアルゴリズム
	 * @return
	 */
	private static String hash(String input, String algorithm) {

		MessageDigest digest;
		try {
			digest = MessageDigest.getInstance(algorithm);
			digest.update(input.getBytes());
		}
		catch (NoSuchAlgorithmException e) {
			return "";
		}
		return byte2HexString(digest.digest());
	}


	/**
	 * バイトコードを16進数文字列に変換
	 *
	 * @param input
	 * @return
	 */
	public static String byte2HexString(byte[] input) {

		StringBuffer buff = new StringBuffer();
		int count = input.length;
		for(int i= 0; i< count; i++){
			buff.append(Integer.toHexString( (input[i]>> 4) & 0x0F ) );
			buff.append(Integer.toHexString( input[i] & 0x0F ) );
		}
		return buff.toString();
	}

}

おしまい。