住民登録番号が消えた場所に生まれたもの — CI(連携情報)の正体 🔐

“あなたの住民登録番号は消えましたが、その影は依然としてインターネットをさまよっています。”

>

🎯 この記事で扱うこと

  • CI(Connecting Information)とは何か、なぜ作られたのか
  • CIが88バイトである理由 — ハッシュアルゴリズムの秘密
  • CI生成過程(住民登録番号 → HMAC → Base64)
  • CI vs DI、違いとそれぞれの用途
  • CIをめぐる個人情報保護論争

📌 導入 / 背景 — 住民登録番号をなくそうとして生まれたもの

2014年、大韓民国は民間企業による住民登録番号の収集を原則的に禁止しました。数年間にわたって繰り返された大規模な個人情報流出事故がその背景にありました。カード会社、通信会社、ショッピングモール — どこにでも住民登録番号が蓄積されており、流出するたびに数千万件ずつ漏洩しました。

しかし、問題が発生しました。住民登録番号が使えなくなると、オンラインで「この人があの人と同じ人物なのか」をどうやって確認するのかということです。例えば、AショッピングモールとBポイントアプリが提携サービスを連携する際、両サービスに登録した「ホン・ギルドン」が同一人物であるかを確認する手段が必要でした。

そこで誕生したのが、まさにCI(Connecting Information)、連携情報です。

CIは、オンラインで異なるインターネット事業者間で同一人物を識別するために使用され、本人確認機関が住民登録番号を暗号化して生成した88バイトの情報です。


🔍 CIとは正確には何か?

CIの定義

CI(Connecting Information)は、特定個人の識別を目的とした固有の汎用Key値です。住民登録番号に基づいて生成されるため一意性が保証され、一方向暗号化を利用するため復号化は不可能です。

簡単に言えば、住民登録番号をハッシュで処理した後、Base64でエンコードした88文字の文字列です。

実際のCI値の例は以下のようになります:

wEi9oYSuekQGxT9MV4rKHG4CO+Zrp+onhLIIuembI8jx/0PLF5Ne3oMBxvUFlN4UmsgjeNErZfmpCVUFH..

英大文字小文字 + 数字 + 特殊文字(+、/、=)が混ざった88文字です。どこかでよく見かけましたか?そうです。Base64エンコーディング特有の形式です。

なぜ88バイトなのか?

ここで、先の質問の答えが出ます。88バイトは、SHA-512ハッシュ結果をBase64エンコーディングしたときに出てくるサイズです。

ハッシュアルゴリズムとしてはSHA-512暗号化アルゴリズムが使用されます。

段階 説明 サイズ
SHA-512ハッシュ出力 512ビット = 64バイト(バイナリ) 64バイト
Base64エンコーディング 3バイト → 4文字変換 64 × 4/3 ≈ 88文字

つまり、SHA-256ではなくSHA-512 + Base64の組み合わせであるため、88バイトになるのです。✅


🔧 CI生成過程 — 段階別分解

最初の段階として、住民登録番号(RN)と秘密鍵(SA、SK)を組み合わせます。ここで秘密鍵は、本人確認機関とKISAが共有する64バイトの秘密情報です。次に、住民登録番号と秘密鍵が組み合わされた値を、一方向暗号化アルゴリズムであるハッシュ関数で暗号化します。

まとめると以下のようになります:

주민번호 + KISA 공유 비밀키(64바이트)
        ↓
   HMAC-SHA-512 (일방향 해시)
        ↓
    64바이트 바이너리
        ↓
   Base64 인코딩
        ↓
    CI (88바이트 문자열)

ここで重要なのは、単純なハッシュではなくHMAC(Hash-based Message Authentication Code)を使用するという点です。HMACは秘密鍵を一緒に混ぜてハッシュを生成するため、KISAと本人確認機関だけが同じCIを再現できます。

Python類似コード例

import hmac
import hashlib
import base64

# 住民登録番号 + KISA共有秘密鍵
resident_number = "9001011234567"
secret_key = b"KISA_SHARED_SECRET_64BYTES_..."  # 実際の秘密鍵は非公開

# HMAC-SHA512でハッシュを生成
hmac_result = hmac.new(
    secret_key,
    resident_number.encode("utf-8"),
    hashlib.sha512
).digest()  # 64バイトバイナリ

# Base64エンコーディング → 88文字のCI生成
ci = base64.b64encode(hmac_result).decode("utf-8")
print(f"CI 길이: {len(ci)}")  # 88
print(f"CI: {ci}")

⚠️ 実際のKISA秘密鍵は絶対に公開されません。上記のコードは概念理解のための類似コードです。


🆚 CI vs DI — 何が違うのか?

DIはDuplication Informationの略で、64バイトの情報です。サービス内の重複加入会員情報であり、DIは一つのサービスに一つのDIのみが存在します。各サービスごとのDIは互いに異なるため、各サービスを相互に連携するにはCI情報を使用する必要があります。

項目 CI(連携情報) DI(重複加入確認情報)
略語 Connecting Information Duplication Information
サイズ 88バイト 64バイト
一意性 全国すべてのサービスで同一 同じサービス内でのみ同一
用途 サービス間の同一人物連携 特定サービス内での重複加入防止
住民登録番号マッチング 1:1マッチング サイトごとに異なる

簡単な比喩:CIは住民登録番号のようにどこでも使われる全国区ID、DIは特定サイトでのみ通用するメンバーシップ番号です。


⚠️ 注意事項 / CIをめぐる論争

1. 「第二の住民登録番号」問題

連携情報は、住民登録番号をハッシュ関数を利用して変換し、「本人確認機関間で共有される秘密情報」を追加して生成され、一度付与されると住民登録番号を変更しない限り変更できないため、まさに第二の住民登録番号と言えます。

2. 流出時の対応不可

住民登録番号をなくすために導入されたCIですが、住民登録番号と1:1でマッチングされることで、CIで個人識別が可能になりました。流出しても本人は修正権限がないため、対応方法がありません。

3. 個人情報保護法上の暗号化義務

個人情報取扱者は、住民登録番号が紛失・盗難・流出・偽造・変造または毀損されないよう、暗号化措置を通じて安全に保管しなければなりません。これを違反して暗号化措置を講じなかった場合には、3千万ウォン以下の過料が課されます。

CIも個人情報に該当するため、サービス事業者がDBにCIを保存する際は、AES-256などの安全なアルゴリズムで暗号化して保管する必要があります。

一般的にAES-256、SHA-256以上を使用すれば論争の余地はありません。


✅ まとめ / 締めくくり

項目 内容
CI定義 住民登録番号ベースの一方向ハッシュ連携情報
ハッシュアルゴリズム HMAC-SHA-512
サイズ 64バイト(バイナリ) → Base64 → 88バイト
復号化可能か ❌ 不可(一方向)
生成主体 本人確認機関(NICE、KCB、移動通信会社など)
法的規制 個人情報保護法 暗号化義務対象

CIは住民登録番号の代替として誕生しましたが、事実上、住民登録番号と1:1で対応する永続的な識別子です。個人情報保護の側面から依然として論争があり、韓国固有の独特な本人確認システムを理解する上で核心的な概念です。

さらに深く学習したい場合は、KISA本人確認支援ポータル個人情報の安全性確保措置基準案内書(2024年10月版)を参照することをお勧めします。


Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です