日向夏特殊応援部隊

俺様向けメモ

AES_ENCRYPT, AES_DECRYPT可能な暗号をPerlで行う

はじめに

MySQLの関数にAES_ENCRYPT, AES_DECRYPTってのがあります。

AES_ENCRYPT, AES_DECRYPT

Rijndaelを128bitのkeylengthでECBで暗号化する関数です。

AES_ENCRYPT
mysql> SELECT HEX(AES_ENCRYPT('hogehoge', 'abcdeabcdeabcdea')) AS encrypted;
+----------------------------------+
| encrypted                        |
+----------------------------------+
| 2BF77B6863989EAD599D86650A046586 |
+----------------------------------+
AES_DECRYPT
mysql> SELECT AES_DECRYPT(UNHEX('2BF77B6863989EAD599D86650A046586'), 'abcdeabcdeabcdea') AS decrypted;
+-----------+
| decrypted |
+-----------+
| hogehoge  |
+-----------+

この関数を使って値を突っ込んでおけば、管理者のみが知るpassphraseを知らない人は、
復号出来ない文字列をデータベースにいれておけます。

Perlで扱う場合

  • Crypt::ECB
  • Crypt::Rijndael

が必要です。同じように行うならば、

#!/usr/bin/perl

use strict;
use warnings;
use Crypt::ECB;

my $string = 'hogehoge';

my $cipher = Crypt::ECB->new();

$cipher->cipher('Rijndael');
$cipher->key('abcdeabcdeabcdea');
$cipher->padding(PADDING_AUTO);

my $encrypted_hex = $cipher->encrypt_hex($string);
my $decrypted = $cipher->decrypt_hex($encrypted_hex);

print $encrypted_hex . "\n";
print $decrypted . "\n";

のように行えば、MySQLのAES_ENCRYPT, AES_DECRYPTと同等の暗号化を行う事が出来ます。

余談ですけど

Crypt::ECBってCrypt::CBCとかModeを表すモジュールが既に入ってるとtest.plがコケるので、authorにpatchを送りました。

とりあえず、コケても無害ですが念のため。

*** test.pl     2000-12-17 04:21:14.000000000 +0900
--- ../test.pl.diff     2006-11-16 19:28:08.000000000 +0900
***************
*** 10,17 ****
--- 10,19 ----

  foreach $path (@INC) {
      while (<$path/Crypt/*.pm>) {
+       next if (/(ECB|CBC|CFB|OFB|Ctr)\.pm$/);
        s|^.*Crypt/||;
        s|\.pm$||;
+
        print " Found $_.\n" if $crypt->cipher($_) and ++$ok;
      }
  }

test.pl.patchで保存して、

$ patch < test.pl.patch

で適用すれば問題なしです。