Hatena::Grouprubyist

Going My Ruby Way このページをアンテナに追加 RSSフィード

Ruby ロゴ (C) Ruby Association LLC

2010年11月04日(木)

OpenSSL/Ruby 暗号化をしてみる実験スクリプト

| 21:05 |  OpenSSL/Ruby 暗号化をしてみる実験スクリプト - Going My Ruby Way を含むブックマーク はてなブックマーク -  OpenSSL/Ruby 暗号化をしてみる実験スクリプト - Going My Ruby Way  OpenSSL/Ruby 暗号化をしてみる実験スクリプト - Going My Ruby Way のブックマークコメント

古いメモです。

----

OpenSSL/Ruby での暗号化をしてみる実験スクリプト。

簡単な使い方。

(暗号化)
$ ruby crypt.rb plain.txt >ciper.txt
$ ruby crypt.rb -e plain.txt >ciper.txt
$ ruby crypt.rb -c des3 plain.txt >ciper.txt   # 3DES で暗号化

(復号)
$ ruby crypt.rb -d chiper.txt >plain.txt
$ ruby crypt.rb -c des3 -d chiper.txt >plain.txt  # 3DES で復号

デフォルトで暗号化を行う。

入力は標準入力か引数で指定したファイル。出力は標準出力。

key と IV (省略可) を明示的に指定しない場合は、

passsalt (省略可) から key と IV を生成する。

詳細はスクリプトを参照。

$ ruby crypt.rb -h
Usage: crypt [options]
    -c CIPHER        # 暗号名(openssl に依存)。デフォルトは 'aes-256-cbc'
    -p PASSPHRASE    # Key と IV を生成するもと。デフォルトは 'pass'
    -s SALT          # pass と一緒に使う salt-k KEY           # 暗号鍵。こちらを指定時は passsalt は無視。
    -i IV            # IV。-k Key 指定時に使われる。
    -e                               encrypt     # 暗号化を行う。デフォルト
    -d                               decrypt     # 復号を行なう。
    -L                               log enable

(crypt.rb)

#!/usr/bin/env ruby
require 'optparse'
require 'ostruct'
require 'logger'
require 'openssl'

opt = OpenStruct.new
opt.cipher  = 'aes-256-cbc'
opt.pass    = 'pass'
opt.crypt   = :encrypt
log         = Logger.new($stderr)
log.level   = Logger::ERROR

ARGV.options {|arg|
  arg.on('-c CIPHER')       {|cipher| opt.cipher  = cipher        }
  arg.on('-p PASSPHRASE')   {|pass  | opt.pass    = pass          }
  arg.on('-s SALT')         {|salt  | opt.salt    = salt          }
  arg.on('-k KEY')          {|key   | opt.key     = key           }
  arg.on('-i IV')           {|iv    | opt.iv      = iv            }
  arg.on('-e','encrypt')    {         opt.crypt   = :encrypt      }
  arg.on('-d','decrypt')    {         opt.crypt   = :decrypt      }
  arg.on('-L','log enable') {         log.level   = Logger::INFO  }
  arg.parse!
}

c = OpenSSL::Cipher.new(opt.cipher).__send__(opt.crypt)
log.info "#{opt.cipher}"
log.info "#{opt.crypt}"

if opt.key
  c.key = opt.key
  c.iv  = opt.iv ||= c.random_iv
  log.info "key: #{opt.key}"
  log.info "IV : #{opt.iv}"
else
  c.pkcs5_keyivgen(opt.pass, opt.salt)
  log.info "pass: #{opt.pass}"
  log.info "salt: #{opt.salt}"
end

text = ARGF.read
log.info "text: #{text.size} byte(s)"

print c.update(text) + c.final

# vi: ts=2 sw=2 et:

証明書作成などの実験スクリプト

| 21:04 |  証明書作成などの実験スクリプト - Going My Ruby Way を含むブックマーク はてなブックマーク -  証明書作成などの実験スクリプト - Going My Ruby Way  証明書作成などの実験スクリプト - Going My Ruby Way のブックマークコメント

古いメモです。

----

証明書作成、表示、署名検証を行なう 実験スクリプトを作成した。

CA 証明書、CA 鍵、(証明書の)鍵ファイルは事前に用意すること。

使い方

# 証明書作成 (証明書は標準出力に出力される)
$ ./gencert.rb newkey.pem cacert.pem cakey.pem >newcert.pem

# 証明書の内容表示
$ ./cert_dump.rb newcert.pem

# 証明書と鍵の対応のチェック
$ ./cert_check_key.rb newcert.pem newkey.pem

# 証明書の署名検証
$ ./cert_verify.rb newcert.pem cacert.pem

# 鍵の内容表示
$ ./key_dump.rb newkey.pem

(gencert.rb)

#!/usr/bin/env ruby

require 'openssl'

X509_VERSION_3  = 0x2

USAGE = "usage: #{$0} keyfile cacert cakey"
file1 = ARGV.shift or raise ArgumentError, USAGE
file2 = ARGV.shift or raise ArgumentError, USAGE
file3 = ARGV.shift or raise ArgumentError, USAGE

key     = OpenSSL::PKey::RSA.new(open file1)
cacert  = OpenSSL::X509::Certificate.new(open file2)
cakey   = OpenSSL::PKey::RSA.new(open file3)

# シリアルNo.と subject は決め打ち。拡張領域は設定なし
csr = OpenSSL::X509::Certificate.new
csr.version     = X509_VERSION_3
csr.serial      = 1
csr.issuer      = cacert.subject
csr.not_before  = Time.now
csr.not_after   = csr.not_before + (60 * 60 * 24 * 365)
csr.subject     = OpenSSL::X509::Name.new [["C","JP"],["O","x"],["CN","test"]]
csr.public_key  = key.public_key

# 署名アルゴリズムは sha-1withRSAEncryption
digest = OpenSSL::Digest::SHA1.new(csr.to_der)
cert = csr.sign(cakey, digest)
puts cert

# vi: ts=2 sw=2 et:

(cert_dump.rb)

#!/usr/bin/env ruby
require 'openssl'

module Dumpable
  def dump(name)
    obj = __send__(name)

    if block_given?
      puts "=== #{name} === (#{obj.class})"
      obj.each {|x| yield x}
    elsif obj.to_s.size > 60
      puts "=== #{name} === (#{obj.class})"
      puts obj
    else
      puts "#{name} (#{obj.class}) = #{obj}"
    end
  end
end

file = ARGV.shift or raise ArgumentError, "usage: #{$0} certfile"
cert = OpenSSL::X509::Certificate.new(open file)

puts cert.to_text
puts cert.to_pem
puts "=== X.509 info ==="
cert.extend(Dumpable)
cert.dump(:version)
cert.dump(:signature_algorithm)
cert.dump(:serial)
cert.dump(:subject)
cert.dump(:issuer)
cert.dump(:not_before)
cert.dump(:not_after)
cert.dump(:public_key)
cert.dump(:extensions) {|o| puts "#{o.oid} = #{o.value}"}

# vi: ts=2 sw=2 et:

(cert_check_key.rb)

#!/usr/bin/env ruby
require 'openssl'

file = ARGV.shift or raise ArgumentError, "usage: #{$0} certfile keyfile"
cert = OpenSSL::X509::Certificate.new(open file)

file = ARGV.shift or raise ArgumentError, "usage: #{$0} certfile keyfile"
key = OpenSSL::PKey::RSA.new(open file)

puts cert.to_text
puts cert.to_pem

result = cert.check_private_key(key)
puts "check_private_key: " + (result ? "OK" : "NG")

# vi: ts=2 sw=2 et:

(cert_verify.rb)

#!/usr/bin/env ruby
require 'openssl'

file = ARGV.shift or raise ArgumentError, "usage: #{$0} certfile cacertfile"
cert = OpenSSL::X509::Certificate.new(open file)

file = ARGV.shift or raise ArgumentError, "usage: #{$0} certfile cacertfile"
cacert = OpenSSL::X509::Certificate.new(open file)

puts cert.to_text
puts cert.to_pem

result = cert.verify(cacert.public_key)
puts "verify: " + (result ? "OK" : "NG")

# vi: ts=2 sw=2 et:

(key_dump.rb)

#!/usr/bin/env ruby
require 'openssl'

file = ARGV.shift or raise ArgumentError, "usage: #{$0} keyfile"
key = OpenSSL::PKey::RSA.new(open file)

puts key.to_text
puts key.to_pem
puts key.public_key

# vi: ts=2 sw=2 et:

公開鍵の取り出し (標準出力への表示)

$ openssl x509 -pubkey -noout < mycert.pem
または、
$ openssl rsa -pubout < mykey.pem