株式会社パレットリンクの@y-tsukahara_palettelinkです。
みなさんは、「QRコードを読み取ってWi-Fiに接続してください」という案内を見たことはないでしょうか。
私自身、カフェでこういったQRコードを見かけた際に、「これってどういう仕組みなんだろう?」と疑問に思ったことがきっかけで、この記事を書いてみました。
調べてみると、実はそこまで複雑なことをしているわけではなく、仕組みとしてはかなりシンプルでした。今回は内容整理も兼ねて紹介していきます。
この記事では以下を解説します。
- QRコード自体の仕組み(構造・符号化・誤り訂正)
- Wi-Fi接続QRコードのフォーマット仕様(WIFIスキーム)
- スキャン後にOSが何をしているか、無線接続の暗号化の仕組み
- PythonでWi-Fi QRコードを生成する実装
QRコードの基本
概要
QRコード(Quick Response Code)は、1994年に愛知県のデンソー(現デンソーウェーブ)の開発チームが発明した2次元コードです。自動車部品の工場管理用に生まれ、仕様を公開・特許フリーにしたことで世界中に普及しました。
数字のみなら最大7,089桁、英数字なら4,296文字を1つのコードに格納できます。バーコードが横方向にしかデータを持たないのに対し、QRコードは縦横両方にデータを持つため、同じ面積でおよそ数十倍の情報量を扱えます。
QRコードの内部構造
QRコードをスキャンするとき、読み取り機の内部では「どこにコードがあるか → どの向きか → セルの座標を確定 → 読み方を解釈 → データを復元する」という順番で処理が走ります。各領域がこの流れに対応しています。
切り出しシンボルが3つある理由
4つにしないのは意図的な設計です。3点あれば三角形の頂点として回転角度を一意に決定できます。4つにすると正方形になり、180度回転しても同じ形になるため上下の判別ができなくなります。
マスクパターンとは何か
QRコードのデータ領域が特定のパターン(たとえば全部黒など)に偏ると、読み取り機が誤認識しやすくなります。それを防ぐため、データのビットパターンに対して8種類の「マスク(XOR)」をかけてみて、読み取りやすさのスコアが最も高いマスクを選んで使います。フォーマット情報には「どのマスクを使ったか」が記録されており、デコード時にはその逆マスクをかけることで元のデータに戻します。
符号化の流れ
文字列がQRコード画像になるまでの手順は以下のとおりです。
モード選択は格納効率に直結します。数字だけなら1文字あたり約3.3ビット、英数字なら約5.5ビット、バイト(UTF-8など)なら8ビット固定です。"WIFI:T:WPA;S:…" のような文字列は記号を含むためバイトモードで符号化されます。
誤り訂正:Reed-Solomon符号
QRコードの「汚れていても読める」特性を支えているのがReed-Solomon(リード・ソロモン)符号です。
まず「何が問題か」を整理する
QRコードが壊れるとは、白黒のセル(モジュール)が汚れや傷で正しく読めなくなることです。このとき「どのセルが壊れているか」は分からない状態で、手元には壊れた後のデータしかありません。Reed-Solomon符号はこの状況でも元のデータを復元できます。
仕組みの核心:冗長データであらかじめ「答え合わせ」を仕込む
元データを100個のコードワード(8bitの単位)とします。ここに「誤り訂正用のコードワード」を追加して記録しておきます。読み取り時に壊れた箇所があっても、この冗長データを使って計算し直すことで元の100個を復元できます。
冗長データが多いほど復元能力は上がりますが、その分QRコードのサイズも大きくなります。
冗長コードワードが 2t 個必要な理由
訂正できるコードワード数を t とするとき、必要な冗長コードワード数は 2t になります。
「壊れているのが何番目のコードワードか(位置の特定)」と「そこにあるべき正しい値は何か(値の復元)」の2つを同時に解く必要があるため、手がかりが2倍必要になります。たとえば t=15(15コードワードを訂正したい)なら、冗長コードワードは30個必要です。
実例:電車のホームドア制御
誤り訂正の重要性が分かりやすい事例が、都営地下鉄浅草線で採用されているQRコードを使ったホームドア開閉制御システムです。
車両ドアのガラス部分に貼り付けたQRコードをホーム上部のスキャナーで読み取り、ドア数・編成車両数などの情報を取得することで車両ドアとホームドアを連動して開閉します。
ホームドア開閉制御システムでは、誤り訂正機能をさらに強化した専用QRコード「tQR」が採用されています。最大50%が欠損しても読み取れるよう設計されており、影・汚れ・振動など実環境で発生するノイズへの耐性を高めています。
誤り訂正レベルの選び方
| レベル | 全コードワードに対する復元率 | 用途の目安 |
|---|---|---|
| L | 約7% | データ量を優先したい場合 |
| M | 約15% | 一般的な用途(デフォルト) |
| Q | 約25% | 工場・印刷物など汚れやすい環境 |
| H | 約30% | 破損が多い環境 |
レベルを上げるほど復元能力が上がりますが、誤り訂正コードの分だけセル数が増えるためQRコード全体のサイズも大きくなります。同じデータ量でもHはLの約1.5倍の面積になります。
壁に貼るWi-Fi QRコードは汚れや端の破れのリスクがあるため、Mレベル以上が推奨です。
Wi-Fi QRコードのフォーマット
中身はただの文字列
Wi-Fi接続用QRコードに入っているのは以下の形式のプレーンテキストです。特別なバイナリ形式ではありません。
WIFI:T:<認証方式>;S:<SSID>;P:<パスワード>;H:<隠しSSID>;;
| フィールド | キー | 値 | 必須 |
|---|---|---|---|
| 認証方式 | T |
WPA / WEP / nopass
|
✓ |
| SSID | S |
ネットワーク名 | ✓ |
| パスワード | P |
パスワード文字列 | WPA/WEP時 |
| 隠しSSID | H |
true / false
|
- |
フィールドの区切りは ;、レコードの終端は ; をもう1つ付けて ;; で表します。末尾の ;; を忘れると一部のデバイスで認識されないことがあります。
具体例
# WPA2 パスワードあり(最も一般的)
WIFI:T:WPA;S:CafeGuest;P:welcome2024;;
# パスワードなし(オープンネットワーク)
WIFI:T:nopass;S:FreeWifi;;
# 隠しSSID(SSID非公開のネットワーク)
WIFI:T:WPA;S:HiddenNet;P:secret;H:true;;
特殊文字のエスケープ
SSIDやパスワードに ; \ , " が含まれる場合、フィールド区切りと混同されないようバックスラッシュでエスケープする必要があります。
| 文字 | エスケープ後 | エスケープが必要な理由 |
|---|---|---|
\ |
\\ |
エスケープ文字そのものだから |
; |
\; |
フィールド区切り文字だから |
, |
\, |
予約文字だから |
" |
\" |
文字列の囲み文字だから |
たとえば SSID が Cafe;Network の場合、そのまま書くと ; がフィールド区切りと解釈されます。
# NG:; がフィールド区切りになってしまう
WIFI:T:WPA;S:Cafe;Network;P:pass123;;
# OK:エスケープ済み
WIFI:T:WPA;S:Cafe\;Network;P:pass123;;
家庭・オフィスの一般的なSSIDやパスワードではほとんど問題になりませんが、業務利用で不特定多数のSSIDを扱う場合は意識しておく必要があります。
スキャン後にOSが何をしているか
処理の全体像
カメラアプリがQRコードをデコードして得た文字列が WIFI: で始まっていると、OS側のQRコード解析処理がWi-Fi設定情報として認識し、Wi-Fi設定APIへ接続情報を引き渡します。
iOS / Android それぞれの内部処理
OSは、QRコードから取得したSSID・パスワード・認証方式を、各プラットフォームのWi-Fi設定APIへ引き渡します。
つまりQRコード自体がWi-Fi接続しているわけではなく、QRコードはあくまで「Wi-Fi設定情報を渡す役割」を担っています。
その後はOS側が、
- 周囲のアクセスポイントをスキャン
- 指定SSIDを検索
- WPA/WPA2認証
- 暗号鍵生成(4-Way Handshake)
- 通信開始
までを自動で実行します。
ユーザーから見ると「QRコードを読み込んだら接続できた」ように見えますが、実際にはOSのWi-Fiスタックが接続処理を引き継いでいます。
実際の無線接続:4-Way Handshake
Wi-Fi APIが呼ばれた後、無線レベルでは4-Way Handshake(4ウェイハンドシェイク)という手続きで暗号鍵が確立されます。「なぜパスワードを直接通信路に流さないのか」「なぜ毎回同じ鍵を使わないのか」を理解するための核心部分です。
前提:PMKの導出
QRコードから取得したパスワードは、そのまま暗号鍵になるわけではありません。まず両者(クライアントとAP)が独立に以下の計算でPMK(Pairwise Master Key)を導出します。
PMK = PBKDF2(HMAC-SHA1, パスワード, SSID, 4096回反復, 256bit)
PBKDF2は意図的に計算コストを高くしてあり、総当たり攻撃を遅くする役割があります。
4-Way Handshakeのシーケンス
各メッセージで何を確認しているかを整理します。
| メッセージ | 送信者 | 目的 |
|---|---|---|
| Message 1 | AP → STA | APがセッション用の乱数(ANonce)を渡す |
| Message 2 | STA → AP | STAの乱数(SNonce)を送り、MICで「正しいPMKを知っている」ことを証明 |
| Message 3 | AP → STA | MICを検証してSTAを認証後、GTKをPTKで暗号化して配布 |
| Message 4 | STA → AP | GTK受領を確認。これで両者の鍵が揃い通信開始 |
PTKが毎回違う理由
PTKはANonce・SNonce・両者のMACアドレスから計算されます。ANonceとSNonceは接続ごとに新しく生成される乱数なので、同じパスワードを使っていてもPTKはセッションごとに変わります。
これにより鍵の使い回しを防いでいます。ただし WPA2-PSK は完全な前方秘匿性(PFS)を持つわけではなく、後からPSK(パスワード)が漏洩するとキャプチャ済みHandshakeからPTKを再計算できる点には注意が必要です。
MICとは何か
MIC(Message Integrity Code)はHMACベースの認証タグです。Message 2でSTAはSNonceとMICを送りますが、このMICはPTKのKCK(Key Confirmation Key)部分を使って計算します。APはKCKを使って同じ計算をし、値が一致すればSTAが正しいPMKを持っていることが証明されます。パスワードそのものは通信路を流れません。
| 鍵 | 意味 | 用途 |
|---|---|---|
| PMK(Pairwise Master Key) | パスワードをPBKDF2でハッシュした256bitの鍵 | PTK導出のベース |
| PTK(Pairwise Transient Key) | セッションごとに生成される一時鍵(KCK + KEK + TK) | ユニキャスト通信の暗号化 |
| GTK(Group Transient Key) | APが管理するグループ鍵 | ブロードキャスト・マルチキャストの暗号化 |
公衆Wi-FiでPMK(=パスワード)が広く共有されている場合、4-Way HandshakeをキャプチャされるとPTKを総当たりで計算できてしまいます。同じパスワードを知っている人間は全員の通信を盗聴できる状態になるため、ゲストネットワークをメインネットワークとVLANで分離することが重要です。
Python実装
必要なライブラリ
pip install "qrcode[pil]"
Wi-Fi QRコードを生成する
最小構成はこれだけです。
import qrcode
ssid = "Cafe_Free_Wifi"
password = "password123"
security = "WPA"
wifi_config = f"WIFI:T:{security};S:{ssid};P:{password};;"
img = qrcode.make(wifi_config)
img.save("wifi_qr.png")
print("作成完了")
qrcode.make() は内部的にバージョン・誤り訂正レベル(デフォルトM)・マスクパターンを自動選択して最適なQRコードを生成します。
SSIDやパスワードに ; \ , " が含まれるときはバックスラッシュでエスケープが必要です。
例:Cafe;Network → Cafe\;Network
実際にやってみた
実際に自宅のWi-Fi情報からQRコードを生成し、コンビニでシール印刷して壁に貼ってみました。
スマホのカメラで読み取るだけで接続画面が表示されるので、
来客時に毎回パスワードを伝えなくて済むようになります。
特に iPhone はカメラを向けるだけで接続通知が出るのでかなり快適です。
実際に壁へ貼ったWi-Fi QRコード
セキュリティ上の観点からSSID・パスワード部分にはモザイク処理を入れています。
セキュリティ上の注意点
QRコードの中にはパスワードが平文で格納されています。以下の点を意識してください。
| リスク | 対策 |
|---|---|
| QRを撮影されるとパスワードが漏れる | ゲストネットワークを社内ネットワークとVLANで分離する |
| 同じPMKを共有すると通信が盗聴されうる | パスワードを定期的に変更しQRコードを再生成する |
| QRコードを偽造したフィッシング | 公式掲示物であることを明示する(ロゴ・封印シールなど) |
まとめ
QRコードからWi-Fiに繋がる仕組みは「決まった書式の文字列をQRに入れ、OSがそれを解釈してWi-Fi APIを呼ぶ」というシンプルな設計です。ただしその裏では、Reed-Solomon符号による誤り訂正やPBKDF2・4-Way Handshakeによる鍵交換といった堅牢な仕組みが動いています。
参考資料
- デンソーウェーブ「QRコードとは」 - QRコードの公式技術情報
- デンソーウェーブ「誤り訂正機能について」 - 誤り訂正レベルの詳細
- メディアシーク「QRコードの誤り訂正の限界について」 - Reed-SolomonブロックとQRコードの関係
- Siglead「リードソロモン符号」 - Reed-Solomon符号の数学的解説
- SEの道標「WPA2の仕組みと4-Way Handshake」 - PTK/GTKと4-Way Handshakeの図解
- サイレックス・テクノロジー「WPA3のはなし」 - WPA/WPA2/WPA3の鍵生成の比較
パレットリンクでは、日々のつながりや学びを大切にしながら、さまざまなお役立ち記事をお届けしています。よろしければ、ぜひ「Organization」のページもご覧ください。
また、私たちと一緒に未来をつくっていく仲間も募集中です。ご興味をお持ちの方は、ぜひお気軽にお問い合わせください。一緒に新しいご縁が生まれることを楽しみにしています。