AES共通鍵暗号で文字列を暗号化

要り用だったのでつくった。
まちゅダイアリー irb で覚える共通鍵暗号 (AES)を参考にした。

# aeshex.rb
require 'openssl'
module AESHex

  class Error < RuntimeError; end
  
  def self.key=(str)
    @@encrypter = nil
    @@decrypter = nil
    @@key = str.to_s
  end
  
  private
  def self.key
    @@key
  rescue NameError => e
    raise AESHex::Error.new('The key is not specified.')
  end

  def self.cipher
    OpenSSL::Cipher::Cipher.new("AES-256-CBC")
  end

  def self.encrypter
    if key && @@encrypter.nil?
      @@encrypter = cipher
      @@encrypter.encrypt
      @@encrypter.pkcs5_keyivgen(key)
    end
    @@encrypter
  end

  def self.decrypter
    if key && @@decrypter.nil?
      @@decrypter = cipher
      @@decrypter.decrypt
      @@decrypter.pkcs5_keyivgen(key)
    end
    @@decrypter
  end

  def self.clear
    @@decrypter = @@encrypter = nil
  end

  public
  def self.encrypt(str)
    clear
    result = encrypter.update(str)
    result << encrypter.final
    result.unpack("H*")[0]
  end

  def self.decrypt(str)
    clear
    result = decrypter.update([str].pack("H*"))
    result << decrypter.final
    result
  end

  def self.included(receiver)
    String.class_eval <<-EVAL

def encrypt
  AESHex.encrypt(self)
end

def decrypt
  AESHex.decrypt(self)
end

EVAL
  end

end

こんな感じに使う。

$KCODE = 'u'
require 'aeshex'
AESHex.key = 'test'
str = AESHex.encrypt(<<-TEXT)
AES共通鍵暗号をつかった暗号化ライブラリです。
必要になったので作りました。
TEXT
# => => "96676df22c712131c24de80c4892e2b8349d4ffa8ff58076c85bb75c70195834df38fce4026837d2ea04320c26a27e8a513bc68bc22c56bc15c6003f7a7b5503d285ad70403cb31f96e91e05d0e10d97276b0fdd7f795eed991bceba8659bb49ab95b1ddba5fcb9d7e23add7f37b6235"
AESHex.decrypt(str)
# => "AES共通鍵暗号をつかった暗号化ライブラリです。\n必要になったので作りました。\n"

# includeすることでStringクラスを拡張する。
include AESHex
str = "String#encrypt及びString#decryptが追加される".encrypt
# => "3ad880ddacc22e9dda5a4a65a5e7826926bc26269537ef249cb330721b40869c7613078928e569a5614bb0cd5456d4d2de905dd4137027e5b0e9f6e03211438a"
str.decrypt
# => "String#encrypt及びString#decryptが追加される"