暗号化は大別すると2種類があります。
すなわち秘密鍵形式と公開鍵形式です。
復号可能か否かじゃないのか、と言われれば復号化できないのは暗号化ではなくハッシュなので違います。
今回は取り扱いが簡単な秘密鍵形式の暗号化を行ってみます。
秘密鍵形式の暗号化とは、いわゆる暗号化です。
'A'を'D'に変換するカエサル暗号を始め、暗号化のキーがわかればたちどころに復号化できるという暗号化です。
予め両者が暗号化キーを知っておく必要があるため、汎用的な暗号化としては適していません。
最初にキーを送る時点では暗号化できないので、ネットから送った時点でそれを傍受されてしまうと無駄になってしまうからです。
ただ、特定の会社間、会社と社員間など、ネットを介さずにキーを設定できる経路であれば十分に役立ちます。
まあとりあえず使ってみましょう。
PHPではMcryptやPEAR::Crypt_Blowfishパッケージがあります。
http://jp.php.net/manual/ja/book.mcrypt.php
http://pear.php.net/package/Crypt_Blowfish
今回はPHPモジュールなんで早そうなMcryptを使用してみます。
暗号化を行う関数であるところのmcrypt_encryptですが引数が多くてよくわかりません。
$cipherは暗号化形式です。
http://jp.php.net/manual/ja/mcrypt.ciphers.php
残念ながらAESは無いみたいなので3DESを使用します。
$keyはいわゆる暗号化キーです。
$dataは暗号化する文字列です。
$modeは暗号化メカニズムらしいです。
http://jp.php.net/manual/ja/mcrypt.constants.php
http://ja.wikipedia.org/wiki/%E6%9A%97%E5%8F%B7%E5%88%A9%E7%94%A8%E3%83%A2%E3%83%BC%E3%83%89
http://www.triplefalcon.com/Lexicon/Encryption-Block-Mode-1.htm
下のサイトがわかりやすいですが、EBCだと暗号化の単位が完全にブロックで分かれているため、解読されやすかったりブロック丸ごと入れ替えられたりという攻撃に会いやすいようです。
$ivはマニュアルだとなんのことだかわかりません。
例えば上記CBCを使用すると、現ブロックの暗号化を行うときに前のブロックのデータを使用して暗号化します。
その場合、最初のブロックには前のブロックがないので、そのかわりに$ivを与え、それを使用して最初の暗号化を行います。
mcript.class.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
class Mcrypt{
//暗号で使う変数
private $enc=array(
'cipher'=>MCRYPT_3DES
,'key'=>''
,'mode'=>MCRYPT_MODE_CBC
,'iv'=>''
);
//暗合する文字列
private $enc_data='';
//復号する文字列
private $dec_data='';
//コンストラクタ
public function __construct($key){
//暗号化キー
$this->enc['key']=$key;
}
//暗号化
public function encrypt($data){
//平文
$this->enc_data=$data;
//IV
if(empty($this->enc['iv'])){
$this->setIV();
}
//暗号化
$this->val=mcrypt_encrypt(
$this->enc['cipher']
,$this->enc['key']
,$this->enc_data
,$this->enc['mode']
,$this->enc['iv']
);
return $this->val;
}
//復号化
public function decrypt($data,$iv=false){
//暗号文
$this->dec_data=$data;
//IV
if($iv){
$this->enc['iv']=$iv;
}
//戻す
$this->val=mcrypt_decrypt(
$this->enc['cipher']
,$this->enc['key']
,$this->dec_data
,$this->enc['mode']
,$this->enc['iv']
);
return $this->val;
}
//IV取得
public function getIV(){
if(empty($this->enc['iv'])){
return $this->_setIV();
}else{
return $this->enc['iv'];
}
}
//IVセット
public function setIV(){
$ivsize=mcrypt_get_iv_size(
$this->enc['cipher'],$this->enc['mode']
);
$this->enc['iv']=mcrypt_create_iv($ivsize,MCRYPT_RAND);
}
#クラスのおわり}
|
mcrypt.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
//準備
require_once('mcrypt.class.php');
$crypt=new Mcrypt('hogehoge');
//暗号化するデータ
$data='hoge';
//暗号化
$enc_data=$crypt->encrypt($data);
$iv=$crypt->getIV();
//復号化
$dec_data=$crypt->decrypt($enc_data,$iv);
|
最終的に関数ふたつだけなのでわざわざクラス化するほどのものでもないのですが、これで纏まりました。
他にmcrypt_enc_get_supported_key_sizesなんかが欲しいと思えばラッピングしていくといいかもしれません。
公式がMcryptクラスを作成してくれればそれでおわりなんですがね。