「XOR暗号化」という言葉を聞いたことはありますか?
プログラミングやセキュリティを学ぶ上で必ず登場する基礎的な暗号技術で、仕組みはシンプルながら、現代の高度な暗号方式の基礎にもなっています。
この記事では、XOR演算の基礎から暗号化の仕組み、実装例、そして弱点まで順を追って解説します。
XOR(排他的論理和)とは
XOR暗号化を理解するには、まずXOR(排他的論理和)という演算を知る必要があります。
XORは「2つの値が異なるときに1、同じときに0を返す」演算です。
英語では「eXclusive OR」と書き、プログラムでは ^ 記号で表すことが多いです。
XORの真理値表
| 入力A | 入力B | 結果(A XOR B) |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
| 「2つの値が違うなら1、同じなら0」と覚えると分かりやすいです。 |
XORの重要な性質
XOR暗号化を支える核心的な性質が「同じ値でXORすると元に戻る」ことです。
A XOR B = C
C XOR B = A (元に戻る)
具体例を見てみましょう。
平文: 0101 1010 (例:文字「Z」のビット列)
鍵: 1100 1100
-----------------
暗号: 1001 0110
暗号: 1001 0110
鍵: 1100 1100
-----------------
復元: 0101 1010 (元の「Z」に戻った)
暗号化と復号で同 じ鍵を使う同一の操作でよいという特性が、XOR暗号の最大の特徴です。
XOR暗号化の仕組み
XOR暗号化の手順は非常にシンプルです。
暗号化は「平文の各バイト」と「鍵の各バイト」をXOR演算するだけです。
復号は「暗号文の各バイト」に対して同じ鍵で再度XOR演算するだけです。
鍵が平文より短い場合は、鍵を繰り返し使用します(繰り返し鍵XOR暗号)。
文字列での具体例
平文「Hi」(ASCIIコード: 72、105)と鍵「K」(ASCIIコード: 75)でXOR暗号化する場合を計算します。
'H' (72) XOR 'K' (75) = 3 (暗号化された値)
'i' (105) XOR 'K' (75) = 34 (暗号化された値)
復号:
3 XOR 'K' (75) = 72 → 'H'
34 XOR 'K' (75) = 105 → 'i'
元の文字列「Hi」に戻りました。
XOR暗号化の実装例
Pythonでの実装
def xor_encrypt(text: str, key: str) -> bytes:
"""文字列をXOR暗号化してバイト列を返す"""
text_bytes = text.encode('utf-8')
key_bytes = key.encode('utf-8')
result = bytes([
text_bytes[i] ^ key_bytes[i % len(key_bytes)]
for i in range(len(text_bytes))
])
return result
def xor_decrypt(cipher: bytes, key: str) -> str:
"""XOR暗号文を復号して文字列を返す"""
key_bytes = key.encode('utf-8')
result = bytes([
cipher[i] ^ key_bytes[i % len(key_bytes)]
for i in range(len(cipher))
])
return result.decode('utf-8')
# 使用例
plaintext = "Hello, World!"
key = "secret"
encrypted = xor_encrypt(plaintext, key)
decrypted = xor_decrypt(encrypted, key)
print(f"平文: {plaintext}")
print(f"暗号化: {encrypted.hex()}")
print(f"復号: {decrypted}")
出力例:
平文: Hello, World!
暗号化: 3b000f1e0a5853320c00091052
復号: Hello, World!
JavaScriptでの実装
function xorEncrypt(text, key) {
return Array.from(text).map((char, i) => {
const keyChar = key.charCodeAt(i % key.length);
return char.charCodeAt(0) ^ keyChar;
});
}
function xorDecrypt(cipherArr, key) {
return cipherArr.map((code, i) => {
const keyChar = key.charCodeAt(i % key.length);
return String.fromCharCode(code ^ keyChar);
}).join('');
}
const plaintext = "Hello, World!";
const key = "secret";
const encrypted = xorEncrypt(plaintext, key);
const decrypted = xorDecrypt(encrypted, key);
console.log("暗号化:", encrypted);
console.log("復号:", decrypted);
XOR暗号化の特徴とメリット
処理が非常に高速
XOR演算はCPUが1命令で実行できる最も基本的なビット演算のひとつです。
AESなどの複雑な暗号化と比べて処理速度が圧倒的に速いため、大量データのリアルタイム処理が必要な場面で補助的に使われます。
実装がシンプル
コードが数行で書けるため、組み込みシステムやマイコンなどリソースの少ない環境でも実装できます。
デバッグもしやすく、暗号化の入門として理解しやすい点も利点です。
暗号化と復号が同一操作
同じ関数で暗号化と復号の両方をこなせるため、コードの複雑さが半減します。
XOR暗号化の弱点と注意点
XOR暗号化は理解しやすい反面、単体で使うには深刻なセキュリティ上の弱点があります。
実務でXOR暗号化を使う際は必ずこれらの弱点を理解した上で判断してください。
弱点①:鍵が短いと解読されやすい
繰り返しXOR暗号(鍵が平文より短い場合)は、カパ・テストやフリードマン検定などの統計的手法で鍵の長さを推測できます。
鍵の長さが判明すると、周波数分析で解読できてしまいます。
弱点②:同じ鍵を使い回すと危険(Two-time pad攻撃)
同じ鍵で2つの異なる平文を暗号化すると、暗号文同士をXORするだけで鍵を消去できてしまいます。
暗号A = 平文A XOR 鍵
暗号B = 平文B XOR 鍵
暗号A XOR 暗号B = 平文A XOR 平文B (鍵が消える)
これにより、2つの平文の差分情報が漏れ、解読の手がかりになります。
弱点③:既知平文攻撃に弱い
攻撃者が「平文の一部」と「対応する暗号文」を両方知っている場合、その部分の鍵を直接計算できます。
鍵 = 平文 XOR 暗号文
これにより鍵の一部が判明し、他の暗号文の解読につながります。
弱点④:完全な安全性には「使い捨て鍵」が必要
理論上の完全秘匿性(情報理論的安全性)を実現するには、ワンタイムパッド(鍵が平文と同じ長さで、完全にランダムで、一度しか使わない)である必要があります。
これは実用上、鍵の管理・配送コストが膨大になる難点があります。
XOR暗号化の実際の使われ方
XOR暗号化は単独ではなく、より複雑な暗号方式の一部として広く活用されています。
AES(現代の標準的な暗号化) では、内部処理にXOR演算が多用されています。
ラウンドキーの適用ステップで平文ブロックと鍵をXORする操作がAESの基本構造に組み込まれています。
ストリーム暗号(RC4、ChaCha20など) では、擬似乱数ストリームと平文をXORして暗号化します。
XORの高速性を活かしつつ、乱数の品質で安全性を担保する設計です。
WebSocketのマスキング では、RFC 6455の仕様でクライアントからサーバーへのデータ送信時にXORマスキングが義務付けられています。
悪意あるキャッシュやプロキシによる誤動作を防ぐ目的です。
データ難読化・スクランブル では、ゲームのアセット保護や設定ファイルの軽い秘匿化など、完全な暗号化が不要なシーンで利用されます。
XOR暗号化を使う際のベストプラクティス
単独のXOR暗号化を実務で使う場合は、次の点に注意してください。
鍵は必ず暗号論的に安全な乱数生成器(CSPRNG) で生成してください。random() のような通常の乱数は予測可能なため、暗号鍵として不適切です。
鍵は再利用しないのが原則です。
同じ鍵を複数のデータに使い回すと、Two-time pad攻撃のリスクが生じます。
高いセキュリティが要求されるシステムには、XOR単体ではなくAES-GCM、ChaCha20-Poly1305 などの現代的な認証付き暗号を使ってください。
まとめ
XOR暗号化は「同じ値でXORすると元に戻る」という性質を利用した、最もシンプルな暗号化手法です。
処理が高速で実装も簡単なため、現代の暗号方式(AES・ChaCha20など)の内部処理でも広く活用されています。
一方で、単独で使うと統計的解析や既知平文攻撃に弱く、業務用途では必ず現代的な暗号方式と組み合わせることが求められます。
まずXORの仕組みを理解することは、暗号技術全般を学ぶための重要な第一歩になります。

コメント