スマートカードのUIDをRubyで読み取る

2026-03-31 linux ruby /posts/2026/2026-03-31-pasori-rc-s300.jpg

pcsc_scanでカードを認識できる状態までライブラリのインストールが済んでいる状態を想定しています。まずはgemを追加します。

gem install smartcard

以下のコードを実行すると、カードがリーダーにかざされたときにUIDを読み取って表示するします。

require 'smartcard'

# PC/SCコンテキストの作成
context = Smartcard::PCSC::Context.new

# 接続されているリーダーを探す
readers = context.readers
if readers.empty?
  puts "リーダーが見つかりません"
  exit
end

reader = readers.first
puts "使用リーダー: #{reader}"

# カード接続待ちのループ(簡易版)
loop do
  begin
    # カードに接続
    card = Smartcard::PCSC::Card.new(context, reader, :shared, :any)

    # UID取得コマンド (Get Data APDU)
    # 0xFF, 0xCA, 0x00, 0x00, 0x00 (標準的なUID取得命令)
    apdu = [0xFF, 0xCA, 0x00, 0x00, 0x00].pack('C*')
    response = card.transmit(apdu)

    # 応答の解析(最後の2バイトはステータスワード)
    uid = response[0...-2].unpack('H*').first.upcase
    sw1_sw2 = response[-2..-1].unpack('H*').first

    if sw1_sw2 == "9000" # 成功コード
      puts "カードを検出しました! UID: #{uid}"
    end

    card.disconnect
    sleep 2 # 連続読み取り防止
  rescue Smartcard::PCSC::Exception
    # カードがない場合はエラーになるので無視してループ
    sleep 0.5
  end
end

次は、sinatra + chromiumで、UI部分を作り込んでみようと思います。