[PHP]OpenSSLを使った文字列の暗号化と復号

PHP には mcrypt という暗号化に関する拡張モジュールがあるのですが長年放置されてしまっているため現在は OpenSSL を使った暗号化が一般的です。
基本的にはパスワードと初期化ベクトル(Initialization Vector)を用いて暗号化と複合を行います。暗号化に利用できる方式はサーバーによって異なるため、事前に openssl_get_cipher_methods() を使って利用可能な暗号化方式を確認しておきます。

<?php
// 暗号化するデータ
$data = 'Hello, World!';

// パスワード
$password = 'password1234';

// 利用可能な暗号化方式一覧
//$methods = openssl_get_cipher_methods();

// 暗号化方式
$method = 'aes-128-cbc';

// 方式に応じたIV(初期化ベクトル)に必要な長さを取得
$ivLength = openssl_cipher_iv_length($method);

// IV を自動生成
$iv = openssl_random_pseudo_bytes($ivLength);

// OPENSSL_RAW_DATA と OPENSSL_ZERO_PADDING を指定可
$options = 0;

// 暗号化
$encrypted = openssl_encrypt($data, $method, $password, $options, $iv);
var_dump($encrypted);

// 復号
$decrypted = openssl_decrypt($encrypted, $method, $password, $options, $iv);
var_dump($decrypted);

結果は base64_encode() された状態で返ります。元のバイナリデータが必要な場合 $options に OPENSSL_RAW_DATA を指定して下さい。

ログイン用パスワードをデータベースに保管する場合など、復号の必要が無い場合は password_hash() の方を利用するのが安全です。

【参考】 OpenSSL関数(http://php.net/manual/ja/ref.openssl.php)

[PHP]連続投稿を一定時間制限する(クッキーによる簡易ロック)

掲示板等で連続書き込みを簡易的に防止する場合はクッキーを使うのが簡単です。
引数は基本的に「setcookie(クッキー名, 値, 有効期限)」なので、例では有効期限を
現在時刻より300秒(5分)後にセットしてあります。
値はこの場合は何でもいいのでとりあえず「true」としておきました。

1. 書き込み前に投稿フォームのページでクッキーが利用できるかを確認するためのクッキーを発行しておく

<?php
session_start();

// ランダムな文字列を生成
$ticket = md5(uniqid(mt_rand(), true));

// 確認用チケットを発行
setcookie('cookie_ticket', $ticket);
$_SESSION['ticket'] = $ticket;

2. 投稿時にクッキーをチェックし、投稿に成功したら制限をかける

<?php
session_start();

$s_ticket = isset($_SESSION['ticket'])       ? $_SESSION['ticket']       : '';
$c_ticket = isset($_COOKIE['cookie_ticket']) ? $_COOKIE['cookie_ticket'] : '';

if( empty($s_ticket) || $s_ticket !== $c_ticket ){
  echo "クッキーを有効にして下さい";
} else if(isset($_COOKIE["cookie_post"])){
  // 制限された時の処理
  echo "連続投稿はしばらく時間をおいて下さい";
} else {
  // 投稿処理

  // 投稿が完了したら制限用のクッキーを発行する
  $expire = time() + 5 * 60;
  $value = "true";

  // このクッキーが存在する間は投稿を制限
  setcookie('cookie_post', $value, $expire);
}

// チケットを削除
$_SESSION['ticket'] = null;
unset($_SESSION['ticket']);
setcookie ("cookie_ticket", "", time() - 3600);

クッキーはブラウザから簡単に削除出来てしまうため、セキュリティ面ではほとんど意味を成しません。
厳格なロックを掛けるのであればアカウントにログインさせる方式を取る必要があります。
とはいえ、IP制限と併用するなどしてちょっとした手間をかけさせることでいたずらを防止する効果はあります。