RavyPop

=͟͟͞͞(๑=͟͟͞͞(๑•̀=͟͟͞͞(๑•̀д•́=͟͟͞͞(๑•̀д•́๑)=͟͟͞͞

Mac OS XでC#を使えるようにしてみた

C#を"Hello World"レベルから学習していたんですが、いちいちwindowsでやるのも面倒なのでMac OSでもコンパイルできないのか調べてみたらヨユーで出来ました。.NET framework互換の環境を提供しているオープンソースソフトウェアがあるんすね。

 

Mono

 

ダウンロードはこちらから。

 

Download - Mono

 

  1. OSを選択
  2. "Mono MRE Installer"と"Mono MDK Installer"をダウンロード

    f:id:tokihiro_k:20131108190644p:plain

  3. 2つともインストールする

これではれて"/usr/bin/mono"が出来上がります。試しにコンパイルしてみました。

using System;

class hello
{
  public static void Main()
  {
    Console.WriteLine("Hello World");
  }
}

これをコンパイルして実行するとこうなります。

bash-3.2$ mcs hello.cs
bash-3.2$ mono hello.exe 
Hello World

 monoを使う場合は"mcs"でコンパイルするようです。さらに普通なら"hello.exe"と呼ぶだけで実行されますけど、この場合は"mono hello.exe"とするようです。何はともあれで来てよかった!

 

そしてどうでもいんですけど、C#のジャグ配列ってなんか面白いと思った。ネーミング的な意味で。

そんなどうでもいいジャグ配列はこちら。"int"と"array"の間の鍵かっこに半角スペースが入っているのはスペースを入れないとこのブログに鍵かっこが表示されなかったからです。だから特にプログラム的な意味はありません。

 

 
using System;

class jagged
{
  public static void Main()
  {
    int[ ][ ] array = new int[3][];
    array[0] = new int[4];
    array[1] = new int[2];
    array[2] = new int[6];
    Console.WriteLine("array[0]の長さは{0}", array[0].Length);
    Console.WriteLine("array[1]の長さは{0}", array[1].Length);
    Console.WriteLine("array[2]の長さは{0}", array[2].Length);
  }
}

実行結果

bash-3.2$ mcs jagged.cs 
bash-3.2$ mono jagged.exe 
array[0]の長さは4
array[1]の長さは2
array[2]の長さは6

rubyでopenSSLを使う in Mac OS X その2

昨日は単なる文字列の暗号化と復号を行ったので、今日はハッシュとMAC(メッセージ認証コード)をやってみた。というかただ文字のハッシュぐらいなら一瞬でできます。

SHA256を使ってハッシュ値を計算する

require 'openssl'

def make_sha256(str)
  dig256 = OpenSSL::Digest::SHA256.new()
  return dig256.hexdigest(str)
end


if __FILE__ == $0
  plaintext = ARGV[0]
  digest_text = make_sha256(plaintext)
  puts digest_text
end

 

 クラスにしてみました。FileDigestrubyの公式リファレンスに載っていたままです。

 

require 'openssl'

class DigestClass

  def initialize(alg = "sha256")
    @digest = OpenSSL::Digest.new(alg)
  end

  #文字列のハッシュ
  def StringDigest(str)
    return @digest.hexdigest(str)
  end

  #ファイルのハッシュ
  def FileDigest(filename)
    File.open(filename){|f|
      while data = f.read(1024)
        @digest.update(data)
      end
    }
    return @digest.hexdigest
  end

end

#このプログラムが単体で実行される場合のみ以下を実行
if __FILE__ == $0
  plaintext = ARGV[0]
  dig = DigestClass.new()
  digest_text = dig.StringDigest(plaintext)
  file_digest_text = dig.FileDigest("music.mp3")
  puts digest_text
  puts file_digest_text
end

実行結果

bash-3.2$ ruby sha256.rb mengae 
a9b883f252d68ac420757464e749cfc2786b0fba21b2debcecbe70bdcc80fcbe 
513b05c8f9e320e041efac5ea55949f9fa60dad0a4d004504469c89e911c2948

HMACを使ってメッセージ認証コードをつくる

rubyでHMACをつかってみました。といってもほとんどさっきのプログラムの流用で作ったんですけど。暗号鍵は昨日の"create_key.rb"を使って生成しました。
rubyでopenSSLを使う in Mac OS X

鍵に関しては”AES-256-CBC”でいいのか正直よくわからんです(笑

require 'openssl'
require './create_key'

class HmacClass

  def initialize(key, digest = "sha256")
    @hmac = OpenSSL::HMAC.new(key, digest)
  end

  #文字列のメッセージ認証コード
  def HmacStringDigest(str)
    @hmac.update(str)
    return @hmac.hexdigest
  end

  #ファイルのメッセージ認証コード
  def HmacFileDigest(filename)
    File.open(filename){|f|
      while data = f.read(1024)
        @hmac.update(data)
      end
    }
    return @hmac.hexdigest
  end

end

#このプログラムが単体で実行される場合のみ以下を実行
if __FILE__ == $0
  plaintext = ARGV[0]
  ck = Create_key.new("AES-256-CBC")
  key = ck.key_gen
  hm = HmacClass.new(key, "sha256")
  digest_text = hm.HmacStringDigest(plaintext)
  file_digest_text = hm.HmacFileDigest("music.mp3")
  puts digest_text
  puts file_digest_text
end

以下が実行結果です。

bash-3.2$ ruby hmac.rb megane
4cdd884655dd037e523a34620aaf8b6ad8a19f00bdb621302d7b1b9ee122b5c2
6f2b7822f47c961b6c0b78a199fa72c2d65c5a12286231b20cec2fd81c954d67

 

                 

rubyでopenSSLを使う in Mac OS X

一眠りしてから書きました。実行した環境は以下の通りです。

 

  • 環境:Mac OS X 10.9 Marverics
  • ruby: 2.0.0p247 (2013-06-27 revision 41674) [universal.x86_64-darwin13]

 

とりあえず暗号文を表示するためのメソッドを用意します。暗号文をprintするとちゃんと見えないので。

 

def bin_dump(str, num)
  num.times do |i|
    str[i].bytes { |b| print b.to_s(16) }
  end
  puts ""
end

 

"/dev/random"を使って暗号化鍵を生成する

暗号鍵を生成するクラスを作ってみました。こんな感じです。

require 'openssl'

def bin_dump(str, num)
  num.times do |i|
    str[i].bytes { |b| print b.to_s(16) }
  end
  puts ""
end

class Create_key

  def initialize(alg)
    @cip = OpenSSL::Cipher.new(alg)
    OpenSSL::Random.load_random_file("/dev/random")
  end

  #乱数シード変更
  def ch_seed
    OpenSSL::Random.load_random_file("/dev/random")
  end

  #イニシャライズベクタ生成
  def iv_gen
    return @cip.random_iv
  end

  #鍵生成
  def key_gen
    return @cip.random_key
  end

  #鍵長を返す
  def key_len
    return @cip.key_len
  end
end


#このプログラムが単体で実行される場合のみ以下を実行
if __FILE__ == $0
  ck = Create_key.new("aes-256-cbc")
  key = ck.key_gen
  len = ck.key_len
  print "len = ", len, "\n"
  bin_dump(key, len)
end

実行結果

bash-3.2$ ruby create_key.rb
len = 32
cf3dced495f690584a388d2556f87bf10612ab9ffa891cc4dde407175ebb2ad




スペシャルファイル"/dev/random"を乱数シードとして使っています。処理が返ってこない場合はかわりに"/dev/urandom"を使いましょう。少なくともubuntuでは処理が返ってこなくなりました。"if __FILE__ == $0"はコメントにあるようにこのプログラムが単体で実行された場合にのみ、実行されます。だからほかのプログラムからこのクラスを使ったりした場合は無視されるんですよ。便利だね〜。


"/dev/random"とはなにかやなんで処理が返ってこなくなるかはLet's google!

 

文字列の暗号化と復号を行う

 

require 'openssl'
require './create_key'

def bin_dump(str, num)
  num.times do |i|
    str[i].bytes { |b| print b.to_s(16) }
  end
  puts ""
end

class Crypto

  def initialize(key = nil, iv = nil, alg = "aes-128-cbc")
    @cip = OpenSSL::Cipher.new(alg)
    @key = key
    @iv = iv
  end

  def encrypt(s)
    if @key != nil && @iv != nil
      @cip.encrypt              #暗号化モード
      @cip.key = @key           #鍵セット
      @cip.iv = @iv             #イニシャライズベクタセット
      @cip.padding = 1          #パディング有効
      enc_data = ""
      enc_data << @cip.update(s)
      enc_data << @cip.final
      return enc_data
    else
      return nil
    end
  end

  def decrypt(s)
    if @key != nil && @iv != nil
      @cip.decrypt              #復号モード
      @cip.key = @key           #鍵セット
      @cip.iv = @iv             #イニシャライズベクタセット
      @cip.padding = 1          #パディング有効
      dec_data = ""
      dec_data << @cip.update(s)
      dec_data << @cip.final
      return dec_data
    else
      return nil
    end
  end

end



#このプログラムが単体で実行される場合のみ以下を実行
if __FILE__ == $0
  plaintext = ARGV[0]
  ck = Create_key.new("aes-128-cbc")
  key = ck.key_gen
  iv = ck.iv_gen
  c = Crypto.new(key, iv, "aes-128-cbc")
  ciphertext = c.encrypt(plaintext)
  if ciphertext != nil
    print "[ciphertext] : "
    bin_dump(ciphertext, 16)
    b = c.decrypt(ciphertext)
    p b
  else
    print "error\n"
  end
end

実行結果

bash-3.2$ ruby crypto.rb megane
[ciphertext] : 9c2bf5bfe43e984852eaec4b111c7229
"megane"



さっきの鍵生成プログラムをrequireして、暗号鍵と初期化ベクタを生成します。それでもって暗号化したり、復号したりします。実際使う場合は作った鍵をファイルに保存して厳重に管理しましょう。

深く考えずに作ったので色々至らない点もあるかもしれないっす。そしてここまで作って、ClassじゃなくてModuleにした方が良かったのではと思いました。 まぁあとは後々修正していきましょう!

 

 

 

               

openssl is deprecated in Mac OS X 10.7

Mac OS X 10.6.8 から Mac OS X 10.9 へアップデートしました。Xcodeもアップデートして使っていたら、異常な量の警告が現れました。一部の画像がこれです。

 

f:id:tokihiro_k:20131105205030p:plain

 

これらは『openSSL』の関数群です。なぜかいつの間にか非推奨(deprecated)になってたんすね。。。

こちらのブログに色々と書いてありました。

 

Ludovic Rousseau blog: Mac OS X Lion and OpenSSL

 

openSSLとかはやめて、Appleが独自(?)に実装したライブラリ群があるのでそっちを使いなさいよってことみたいです。結論としてはこれから先のMac OSではopenSSLがインストールされないだろうから、素直にAppleのライブラリを使うか自分でopenSSLをいれようぜってこの方は言ってます。

 

でもこれ2011年の記事で2013年の今でも普通にopenSSLはインストールされてるし、自分でインストールするのも簡単だし、別にApple storeに公開するもの作ってるわけじゃないし、今更Appleさんのライブラリを使うように書き換えるのは面倒学習時間がもったいないしなのでしばらくは気にしないでいこうと思いました。

 

そしてなんのため独自のライブラリなのかって点は2011年のWWDCでdeveloper向けの資料に書いてあるそうです。

 

Why is Apple Deprecating OpenSSL in MacOS 10.7 (Lion)? - Stack Overflow

 

Stack Overflowでの回答者が言ってる手順でその資料を見に行けました。

  1. Apple Developerに入る

  2. topページの下にあるDeveloper用の項目の"Videos"をクリック

    f:id:tokihiro_k:20131105211653p:plain

  3. WWDC 2011 Videosをクッリク
  4. なかほどまでスクロールして"Next Generation Cryptographic Service"をクリック
  5. プレゼンスライドがGetできる!

 

そしてずっと下の方にopenSSLの件に関して書いてあるみたいでした。英語読むの疲れたので結局この資料はちゃんと見てないとです(*´-ω-`)・・・フゥ

でも普通に考えたらOSに最適化されたライブラリ使った方がOSとアプリケーションの親和性的な何かがよくなるだろうしきっとそういうことなんだろう(適当)

 

もし気が向いたらAppleのCC_cryptoに切り替えよう。