プロが教えるわが家の防犯対策術!

Rubyでファイルを暗号化し、それを復号したいのですがうまくいかないため、
質問させていただきます。

Ruby 1.9.3を使用しています。

・ファイルの暗号化 encrypt.rb
-------------------------------------------------
# encoding: cp932

require 'openssl'

def encrypt(file, pass)
  enc = OpenSSL::Cipher::AES256.new('CBC')
  enc.encrypt
  enc.pkcs5_keyivgen(pass)
  File.open(file, 'rb') do |fin|
    File.open("#{file}.sec", 'wb') do |fout|
      while buff = fin.read(8000)
        fout.write(enc.update(buff))
      end
      fout.write(enc.final)
    end
  end
  enc.reset
end

if $*.length > 0
  print 'password: '
  pass = $stdin.gets.chomp
  $*.each do |arg|
    begin
      encrypt(arg, pass)
      puts "#{arg}を暗号化したファイル#{arg}.secを作りました。"
    rescue
      puts "#{arg}の暗号化に失敗しました。"
    end
  end
  0.upto(pass.length - 1) do |i|
    pass[i] = '\xff'
  end
end

-------------------------------------------------


・ファイルの復号 decrypt.rb
-------------------------------------------------
# encoding: cp932

def decrypt(file, pass)
  dec = OpenSSL::Cipher::AES256.new('CBC')
  dec.decrypt
  dec.pkcs5_keyivgen(pass)
  File.open(file, 'rb') do |fin|
    File.open("#{file}.plain", 'wb') do |fout|
      while buff = fin.read(512)
        fout.write(dec.update(buff))
      end
      fout.write(dec.final)
    end
  end
  dec.reset
end

if $*.length > 0
  print 'password: '
  pass = $stdin.gets.chomp
  $*.each do |arg|
    begin
      decrypt(arg, pass)
      puts "#{arg}を復号したファイル#{arg}.plainを作りました。"
    rescue
      puts "#{arg}の復号に失敗しました。"
    end
  end
  0.upto(pass.length - 1) do |i|
    pass[i] = '\xff'
  end
end

-------------------------------------------------

コマンドプロンプトでencrypt.rb自身を暗号化し、encrypt.rb.secの作成はできるのですが、
decrypt.rbを実行してパスワードを入力しても復号ができません。
どのようにすれば復号できるのか教えていただけますでしょうか。

A 回答 (2件)

ファイルの復号 decrypt.rb


のほうですが、
require 'openssl'
が抜けています。

# encoding: cp932
の次の行へ
require 'openssl'
を追加してください。

この回答への補足

回答ありがとうございます。
無事、ファイルを復号することができました。

もう一点、教えていただきたいのですが、
暗号化の際にAES256クラスを使用した場合、キー長は256ビットとなるのですが、
例えばパスワードを'abc'としても暗号化することができました。
パスワードはキーと同じものだと考えていたのですが、
そうであればパスワードの長さも記号と英数字合わせて32バイトにする必要はないのでしょうか。

補足日時:2014/12/24 19:58
    • good
    • 0

> パスワードはキーと同じものだと考えていたのですが、


いいえ、(少なくともこの例では)違います。

instance method OpenSSL::Cipher#pkcs5_keyivgen
http://docs.ruby-lang.org/ja/2.0.0/method/OpenSS …

上記ページに記載されているとおり
pkcs5_keyivgenメソッドは
pass(と指定されていればsalt)からキーとIVを生成します。
passをそのままキーにしているわけではありません。
    • good
    • 0
この回答へのお礼

再度回答いただきありがとうございます。

パスワードがそのままキーになっているわけではないため、
パスワードが'abc'でも暗号化することができたのですね。
リファレンスマニュアルを見て、さらに勉強していきたいと思います。
ありがとうございました。

お礼日時:2014/12/24 21:05

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!