SyuchiNikuRingの備忘録

お勉強したことをまとめておく場所。中の人の理解や感覚で書いているから不正確なことも多いかも。

暗号処理をする機器

やっほー。この時間にご飯食べすぎるとこの後眠くなりますよね。

そんなことは置いておいて、前回のエントリ最後に宣言した通り、今回は暗号化処理の機器に関してまとめます。

今回はTPMとHSMに関してまとめます。


TPM(Trusted Platform Module)
暗号鍵の生成・保管、public keyとprivate keyの生成・保存、デジタル署名の生成と検証、プラットフォームの完全性検証が可能。Windowsのドライブ暗号化機能であるBit Lockerも鍵の保存にTPMを用いる。ハードウェアの処理時間や消費電力、電磁波などの特徴から暗号解読を試みる攻撃に対して情報漏洩を防止。
<<<<<主な機能>>>>>

  • Protected Capabilities(保護機能)

保護領域(Shielded Locations:レジスタ・メモリなど機密性を要求する場所)にアクセスするための権限を持つコマンドセット。鍵の管理、乱数生成、そしてシステムの状態にデータを結びつける役割を果たす。

  • Attestation(構成機能)

情報の正確さを確認するプロセス。TPM外の要素がShielded Locations, Protected Capabilities, Root of Trustについて正確さを確認できる。プラットフォームは、自身の完全性に影響する特性の記述の正確さを確認できる。

  • Integrity Measurement and Report(完全性の測定と保存通知)

プラットフォームの完全性に影響するプラットフォームの特性に関する計測値を取得し、それらのMessage Digest値をPCRに保存する。Root of MeasurementはRTM(Root of Trust for Measurement)と呼ばれる。Static RTMは起動時を、Dynamic RTMは信頼できない状態から信頼できる状態への推移をRoot of Measurementとする。完全性の通知(Integrity Report)はPCRに完全性についての計測値を保存する構成証明のための実行プロセス。

  • セキュアブート

TPMで起動時にソフトウェアの改竄を検知する。

<<<<<TPMで管理される鍵>>>>>

  • Signing Keys

非対称鍵でアプリケーションデータとメッセージの署名に利用される。移行の可否を設定可能。

  • AIK Keys(Attestation Identity Keys)

移行可能なSignig Keys。TPMで作成されたデータやPCRレジスタ値への署名のみに使用。

  • Storage Keys

非対称鍵で、データや他の鍵の暗号化・復号に使用される。鍵やTPM外で管理されるデータを暗号化できる。

  • Bind Keys

プラットフォーム上で小さいサイズのデータ(ex. 対称鍵)を暗号化し、別のプラットフォーム上で復号するために用いる。

  • Legacy Keys

TPM外で生成される鍵で署名や暗号操作に使用後、TPMへインポートされる。

  • Authentication Keys

TPMが関連するトランスポートセッション(ホストとTPM間でのデータ交換の際のバスの暗号化)の保護に用いる。

<<<<<TPMの特別な鍵(保証鍵とStorage Root Key)>>>>>

  • 保証鍵(Endorsement Keys)

TPMハードウェアに永続的に組み込まれるPublic KeyとPrivate Keyの鍵ペアで、通常製造時に書き込まれる。Public Keyを使い、正規のTPMかを識別する。プラットフォームの所有者の確立時に所有者許可データの復号とAIK作成に関連するメッセージの復号に使用される。

  • Storage Root Key(SRK)

TPMハードウェアに保存される鍵。アプリケーションが作成する鍵を暗号化・復号するマスタ・キー役割を果たす。ユーザがTPMの所有権を取得するときにSRKが作成され、ユーザ設定がクリアされた後に新たなユーザが所有権を取得した時には新しくSRKが作成される。

<<<<<TPMに含まれる証明書>>>>>

  • Edorsement 証明書

EKのPublic Keyを含む証明書。保証鍵が保護されていることを証明する。

  • プラットフォーム証明書

プラットフォームにより作成され、プラットフォームのセキュリティ要素が保護されていることを証明する。

  • 適合証明書

評価機関により生成され、プラットフォームのセキュリティ特性に関する信用状を発行する依頼人を証明する。

★HSM(Hardware Security Module)
暗号鍵の作成(ハードウェアのRandom Number Generatorを含む)、鍵交換、鍵配送、鍵のインポート/エクスポート、鍵の保管、鍵の破壊(ゼロ化)、改竄の痕跡記録(タンパー証跡)などの管理を行う。

今回はここまで。

攻撃手法種類

やっほー。久しぶりの更新です。

今回は攻撃手法のメモ。正確には暗号破りの手法をまとめます。

そもそも暗号の強度は何で決まるのでしょうか。
暗号の強度は3要素で決まります。
暗号プログラムの複雑さ、鍵の機密性、そして鍵の長さです。

では、それを破ろうとする攻撃手法を見ていきましょう。



  • Brute Force Attack

いわゆる総当たりです。

  • Birthday Attack

ハッシュ関数の値が衝突する場合を探します。n人いるときに誕生日が被る確率は?というパラドクスに基づいています。

  • Meet in the Middle Attack

共通鍵暗号にBirthday Attackを用います。

  • 既知平文攻撃

平文と暗号文のセットが手元にある場合又は暗号文から平文を一部でも推測可能な場合に、その情報を用いて解読します。

  • 選択平文攻撃

解読に都合に良い平文と暗号文を入手できる場合に、その平文と暗号文のセットから解読を試みます。

  • タイミング攻撃

時間計測攻撃ともいわれます。暗号化処理時間がカギの長さに依存する場合、その処理時間の差を統計的に解析して鍵を推測する攻撃です。

  • SPA攻撃(Simple Power Analysis)

単純電力解析ともいわれます。電力の消費量の波形を観測し情報を推測する攻撃です。

  • DPA攻撃(Differential Power Analysis)

電力差解析です。暗号化処理による電力波形の観測を複数回行い、統計的に解析します。SPA攻撃より強力で精度も高いです。

  • プローブ攻撃

チップ内信号線を直接触って暗号化処理中のデータや暗号鍵を解読します。

  • 故障利用攻撃

エラーを意図的に引き起こし正しい処理結果との差を解析して暗号鍵を割り出します。

電磁波解析攻撃です。製品が出す電磁波を解析して暗号処理中のデータや暗号鍵を割り出します。


今回はこんなところで。次回は暗号化処理を行う機器に関してまとめていきます。

Ruby入門season5~継承~

やっほー。久しぶりの更新です。

今回はクラス継承のお話をまとめます。このエントリをもってRubyはいったんおしまい。

とりあえずいってみよー。

継承により親クラスのインスタンス変数とインスタンスメソッドが引き継がれるのでメソッドを踏襲したい場合やマイナーチェンジをしたい場合に使います。
Rubyの継承はこのように書きます。

require ./(継承したいクラス)

class (子クラス) < (親クラス)
end

実際に書いてみました。
ペットショップのプログラムです。
親クラス、子クラス、実行メソッドの順に並んでいます。コードテストにかけた結果、

Line 8: syntax error, unexpected tSYMBEG, expecting ')'
def initialize(name:, price:, length:)
^
Line 12: syntax error, unexpected kEND, expecting $end

と返されました。うーーーん。
テストに使ったのは、
codepad
です。
詳しくはこちらを。実際にテストにかけた結果が載っています。
http://codepad.org/vFhqPx8D

class Creature

  attr_accessor :name
  attr_accessor :price
  attr_accessor :length

  def initialize(name:, price:, length:)
    self.name = name
    self.price = price
    self.length = length
  end

  def profile
    return "#{self.name}#{self.price}円です。全長は#{self.length}mくらいになります。"
  end
end


  require "./Creature" #creatureクラスを継承
  class Fish < Creature
    attr_accessor :swim_speed

    def initialize(name:, price:, length:, swim_speed:)
      #superを用いてCreatureクラスのinitializeメソッドとの共通項をまとめて継承
      super(name: name, price: price, length: length)
      self.swim_speed = swim_speed
    end

    #profileを継承&オーバーライド
    def profile
      return "#{self.name}#{self.price}円です。全長は#{self.length}mくらいです。
      泳ぐ速さは#{self.swim_speed}km/hくらいです。"
    end
  end

  require "./Creature" #Creatureクラスを継承
  class Reptiles < Creature
      attr_accessor :run_speed

      def initialize(name:, price:, length:, run_speed:)
        #superを用いてCreatureクラスのinitializeメソッドとの共通項をまとめて継承
        super(name: name, price: price, length: length:)
        self.run_speed = run_speed
      end

      def profile
        return "#{self.name}#{self.price}円です。全長は#{self.length}mくらいです。
        走る速さは#{self.run_speed}km/hくらいです。"
      end
  end

    #それぞれのクラスを読み込み
    require "./Fish"
    require "./Reptiles"

    fish1 = Fish.new(name:"バショウカジキ", price:750, length:3.3, swim_speed:112)
    fish2 = Fish.new(name:"錦鯉", price:40000000, length:30, swim_speed:16)

    reptile1 = Reptiles.new(name:"バシリスク", price:8000, length:0.6, run_speed:3.6)
    reptile2 = Reptiles.new(name:"ブラックマンバ", price:50000, length:2, run_speed:16)

    creatures = [fish1, fish2, reptile1, reptile2]
    number = 1
    creatures.each do |creature|
      puts "No.#{number} #{creature}"
      number += 1
    end

    puts "どの生き物が気になりますか?"
    creature_number = gets.chomp.to_i

    selected_creature = creatures[creature_number][:name]
    puts "#{selected_creature}ですね。かわいいですよね。おすすめです。"

修正(2018/09/18)**

順番変えるとエラーは一か所のみになりました。
http://codepad.org/Hv9f5I18

Ruby入門season4~クラス分け~

やっほー。今回はクラスを分けることについてまとめていきます。
コードが増えてくると、一つのクラスに詰め込むのは精神衛生上良くないので、クラスを分けます。
分ける際には、require "./クラス"とします。こうすることでファイル内でファイル外のものを読み込めるようになります。
次に標準入力の受付についてです。ようやく登場しましたね。gets.chompを用いて標準入力を受け付けます。ただしこれは常に文字列として受け付けます。数値として受け付けたいときには、gets.chomp.to_iを使います。これで数値として入力を扱えます。
早速やってみます。これが実行クラス側です。

require "./menu"

menu1 = Menu.new(name: "茶碗蒸し", price: 1000)
menu2 = Menu.new(name: "釜めし", price: 1200)
menu3 = Menu.new(name: "寿司", price: 3000)
menu4 = Menu.new(name: "葛餅", price: 600)

#配列に入れる。
menus = [menu1, menu2, menu3, menu4]
#メニューを表示
index = 0
menus.each do |menu|
  puts "#{index}. #{menu.order}"
  index += 1
end

puts "ご注文はお決まりですか"

order_index = gets.chomp.to_i #注文番号を標準入力から受け取る
selected_menu = menus[order_index] #受け付けたメニューを取り出す
puts "ご注文は#{order_index}番の#{selected_menu.name}でよろしいでしょうか"

puts "おいくつになさいますか"
count = gets.chomp.to_i #個数を標準入力から受け取る

puts "お会計は#{selected_menu.total_price(count)}円になります"

そしてこれが分割したクラスです。

class Menu
  attr_accessor :name
  attr_accessor :price
  
  def initialize(name:, price:)
    self.name = name
    self.price = price
  end
  
  def order
    return "#{self.name} #{self.price}"
  end
  
  def total_price(count)
    total_price = self.price * count
    return total_price
  end
end

実行した結果はこんな感じ。
f:id:SyuchiNikuRing:20180909160623p:plain

葛餅の気分なので3を選択します。
f:id:SyuchiNikuRing:20180909160650p:plain

個数を聞かれます。
f:id:SyuchiNikuRing:20180909160716p:plain
個数を入力するとお会計まで計算してくれました。

今回はここまで。

余談ですが、今回からはコードをちゃんと表示できるようになりました。

Ruby入門season3~クラス~

やっほー。今回はクラスに関してまとめます。前回はメソッドをまとめたので自然な流れですね。

 

基本的な考え方や定義の仕方はJavaと同じです。

中の人の好物である茶碗蒸しでクラスを作りました。

f:id:SyuchiNikuRing:20180908081806p:plain

Rubyのクラスはclass / endで定義します。クラス内のインスタンスはattr_accessorで定義します。インスタンスの先頭に「:」が付くので忘れないようにします。

インスタンスの生成は、クラス.newです。Javaによく似ていますね。(Javaはnew クラスでした。)

インスタンスに値を入れるときは、(オブジェクト).(インスタンス)とします。

先ほどのプログラムを実行します。

f:id:SyuchiNikuRing:20180908082201p:plain

うまくいきました。

クラスの中でメソッドを定義していきます。

f:id:SyuchiNikuRing:20180908084230p:plain

Javaとほとんど変わらないですね。実行してみます。

f:id:SyuchiNikuRing:20180908084313p:plain

menu1とmenu2に対してメソッドが確かに呼び出されています。インスタンスに対して呼び出すメソッドをインスタンスメソッドといい、インスタンス変数というものがあります。self.変数とすることで先ほど生成したインスタンスに代入した値をインスタンスメソッド内で呼び出せます。

 

f:id:SyuchiNikuRing:20180909104145p:plain

 

実行します。

f:id:SyuchiNikuRing:20180909102517p:plain

 いい感じですね。

ところで、ここまで①クラスを作ってから②インスタンスを生成し、それから③インスタンスに値を入れるという手順でやってきました。Javaでも同じことをしていましたが、Javaには②③をまとめてできるコンストラクタというものがありました。Rubyにも同じ機能はないのでしょうか。

ちゃんとあります。initializeメソッドといいます。実際にコードを見てみましょう。

f:id:SyuchiNikuRing:20180909114630p:plain

6行目から9行目にかけてinitializeメソッドが定義されていて、インスタンスの定義と値の代入を同時に行っています。そして、23行目でインスタンスmenu1に対してorderメソッドを呼び出しています。orderメソッドを呼び出したとき、まず実行されるのがinitializeメソッドです。ここでインスタンスとその値を受け取り、それをorderメソッドに渡しています、実行結果を見てみましょう。

f:id:SyuchiNikuRing:20180909115056p:plain

うまく出ました。orderメソッドの結果は一行目に出ている通りです。

とはいえ、これではinitializeメソッドで値を代入しているので、呼び出す度にいつも同じ値が呼び出されてしまいます。そこで、initializeメソッドに引数を渡すことで様々な値に対応できるようにしましょう。

f:id:SyuchiNikuRing:20180909120430p:plain

5行目から9行目までのinitializeメソッドではインスタンス変数に引数を渡しています。

その引数は23行目でキーワード引数を用いて具体的な値を代入されています。ここの値を変えれば、キーワード引数に紐づいているメソッドの出力は全て変更できます。

さて実行結果を見てみます。

f:id:SyuchiNikuRing:20180909121009p:plain

うまくいきました。お土産高っ…

Ruby入門season2~メソッド~

やっほー。今回はメソッドのお話。

以前、Javaオブジェクト指向の件でも書きましたが、Rubyオブジェクト指向型言語です。なのでメソッドがあります。

syuchinikuring.hatenablog.com

 

メソッドの定義の仕方は簡単です。def と end でやりたい処理を挟むだけ。

f:id:SyuchiNikuRing:20180907180029p:plain

実行します。

f:id:SyuchiNikuRing:20180907180047p:plain

うるさい客ですね...とまあこんな感じでメソッドは作れます。

引数も当然増やせます。その際、メソッドを呼び出して引数に代入する際には、メソッドの定義順に代入しなければならないことに注意です。

ちなみにこの例はJavaでいうところのpublic voidに当たるメソッドです。では戻り値を返すメソッドはないのでしょうか。...あります!returnを使います。いつもと全く同じです。

f:id:SyuchiNikuRing:20180907181827p:plain

4割引きのセールタイムのメソッドです。実行します。

f:id:SyuchiNikuRing:20180907181908p:plain

いい感じですね。今回はメソッド内で0.6、つまり小数を乗じているので、結果も小数型で出力されています。なので、600円が600.0円という為替の表記のようになっています。

戻り値には真偽値も取れます。その場合にはメソッド名の直後に?をつけます。

f:id:SyuchiNikuRing:20180907183144p:plain

某電機量販店と被っていますが一切関係ありません。地域最安値でなければ割引に応じてくれ、地域最安値であれば割引を拒まれるメソッドです。実行します。

f:id:SyuchiNikuRing:20180907183420p:plain

キレられなくてよかった...price = 12000, area_lowest = 9000なので割引に応じてくれました。メソッドの中でifを使えばさらに細かい処理もできるようになりますね。

 

最後にキーワード引数に関してです。引数が増えると、呼び出す際にどの引数を書いているのか、順番を気にしないといけないので確認するのが面倒です。そこでキーワード引数です。前回のシンボルの件と同じです。

f:id:SyuchiNikuRing:20180907184653p:plain

実行します。

f:id:SyuchiNikuRing:20180907184714p:plain

...ブルジョワですね。ホストクラブメソッドです。引数を代入するところで「:」を使っています。このように書くと、どの引数に何を代入するのかを明確化できていいですよね。

今回はここまで。