# 機能設計書 118-CAPTCHA認証

## 概要

本ドキュメントは、QuickerSite CMSにおける「CAPTCHA認証」機能の設計仕様を定義する。

### 本機能の処理概要

スパムボット等の自動プログラムからの不正アクセスを防止するための画像認証機能である。ランダムな英数字を含むBMP画像を動的に生成し、ユーザーに入力を求めることで、人間であることを確認する。

**業務上の目的・背景**：Webフォームは自動化されたスパムボットの標的になりやすく、大量のスパムメール送信、不正アカウント作成、ブルートフォース攻撃などのリスクがある。CAPTCHA（Completely Automated Public Turing test to tell Computers and Humans Apart）認証により、これらの自動攻撃を防止し、正規のユーザーのみが操作を完了できるようにする。

**機能の利用シーン**：
- 管理画面ログイン（bs_login.asp）
- システム管理者ログイン（ad_login.asp）
- ページメール送信（mailPage.asp）
- パスワード忘れ処理（process_forgotPW.asp）
- ユーザー登録処理
- ゲストブック投稿
- 連絡先メール送信

**主要な処理内容**：
1. ランダムな4文字の英数字コード生成（CreateGUID）
2. コードをセッションに保存（Session("CAPTCHA")）
3. コードを含むBMP画像生成
4. ノイズ効果適用（オプション）
5. 画像をHTTPレスポンスとして出力
6. フォーム送信時にセッション値と入力値を比較検証

**関連システム・外部連携**：
- セッション管理
- ログイン認証システム
- フォーム送信処理

**権限による制御**：認証・非認証に関わらず、CAPTCHA保護対象のフォームで適用。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | バックサイトログイン画面 | 補助機能 | ログイン時のスパム防止認証 |
| 2 | 管理者ログイン画面 | 補助機能 | ログイン時のスパム防止認証 |
| 160 | メールページ | 補助機能 | メール送信時のスパム防止認証 |
| 167 | 登録処理 | 補助機能 | ユーザー登録時のスパム防止認証 |
| 170 | パスワード忘れ処理 | 補助機能 | パスワードリセット時のスパム防止認証 |
| 180 | メール連絡先（FS） | 補助機能 | メール送信時のスパム防止認証 |

## 機能種別

セキュリティ機能 / 画像認証

## 入力仕様

### 入力パラメータ（画像生成時）

なし（captcha.aspへの直接アクセス）

### 入力パラメータ（検証時）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| CAPTCHA | String | Yes | ユーザーが入力したCAPTCHAコード | Session("CAPTCHA")と先頭4文字を比較 |

### 入力データソース

- HTTPリクエストパラメータ（Request.Form("CAPTCHA")）
- セッション変数（Session("CAPTCHA")）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| CAPTCHA画像 | Binary | BMP形式の認証画像（62x25ピクセル） |

### 出力先

- HTTPレスポンス（Content-Type: image/bmp）

### 画像仕様

| 項目 | 値 |
|------|-----|
| フォーマット | BMP（ビットマップ） |
| 幅 | 62ピクセル |
| 高さ | 25ピクセル |
| 色深度 | 8ビット（256色パレット） |
| 文字数 | 4文字 |
| 使用文字 | A-F、0-9（16進数文字） |

## 処理フロー

### 処理シーケンス（画像生成）

```
1. captcha.aspアクセス
   └─ スクリプト開始
2. コード生成
   ├─ CreateGUID(4)呼び出し
   ├─ ランダム4文字生成（A-F、0-9）
   └─ Session("CAPTCHA")に保存
3. ビットマップ準備
   ├─ PrepareBitmap(secureCode)呼び出し
   ├─ 画像サイズ設定（62x25）
   ├─ フォントマップから文字幅・高さ取得
   ├─ 左マージン・上マージン計算
   ├─ カラーマップからランダム色選択
   └─ 各文字をビットマップに描画
4. ノイズ効果（オプション）
   └─ AddNoise()でランダム線追加
5. 画像出力
   ├─ HTTPヘッダー設定
   │   ├─ Content-Type: image/bmp
   │   ├─ Content-Disposition: inline
   │   └─ Cache-Control: no-cache
   └─ BMP形式でバイナリ出力
```

### 処理シーケンス（検証）

```
1. フォーム送信受信
2. CAPTCHA検証
   ├─ Session("CAPTCHA")取得
   ├─ Request.Form("CAPTCHA")取得
   ├─ 両者をLCase()で小文字変換
   ├─ 入力値の先頭4文字を比較
   ├─ 一致 → 処理継続
   └─ 不一致 → err_captchaエラー
```

### フローチャート

```mermaid
flowchart TD
    subgraph 画像生成
    A[captcha.aspアクセス] --> B[CreateGUID&#40;4&#41;]
    B --> C[Session&#40;CAPTCHA&#41;に保存]
    C --> D[PrepareBitmap&#40;&#41;]
    D --> E{NoiseEffect?}
    E -->|Yes| F[AddNoise&#40;&#41;]
    E -->|No| G[SendBitmap&#40;&#41;]
    F --> G
    G --> H[BMP画像出力]
    end

    subgraph 検証
    I[フォーム送信] --> J[CAPTCHA取得]
    J --> K{LCase比較<br>一致?}
    K -->|Yes| L[処理継続]
    K -->|No| M[err_captchaエラー]
    end
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-118-01 | コード長 | CAPTCHAコードは4文字固定 | 全生成 |
| BR-118-02 | 使用文字 | A-Fと0-9の16進数文字のみ使用 | 全生成 |
| BR-118-03 | 大文字小文字無視 | 検証時は大文字小文字を区別しない | 全検証 |
| BR-118-04 | 先頭4文字比較 | 入力値の先頭4文字のみ比較 | 全検証 |
| BR-118-05 | キャッシュ無効化 | 画像はキャッシュされない | 全出力 |
| BR-118-06 | セッション依存 | CAPTCHAコードはセッションに紐づく | 全処理 |

### 計算ロジック

#### コード生成（CreateGUID関数）

```vb
const strValid = "ABCDEF1234567890"
For cGUID = 1 To valLength
    Do
        tmpChr = Mid(strValid, Int(Rnd(1) * Len(strValid)) + 1, 1)
    Loop While tmpChr = Right(tmpGUID, 1)  ' 連続同一文字を回避
    tmpGUID = tmpGUID & tmpChr
Next
```

#### 画像サイズ計算

```vb
' 各文字の幅を合計
For i = 1 To CodeLength
    arrTextWidth(i) = GetCharMap(Mid(secureCode,i,1))(0)
    arrTextWidth(0) = arrTextWidth(0) + arrTextWidth(i)
Next
' 文字間隔を加算
arrTextWidth(0) = arrTextWidth(0) + ((CodeLength - 1) * CharTracking)
' 左マージン計算（中央配置）
LeftMargin = Round((ImageWidth - arrTextWidth(0)) / 2)
```

## データベース操作仕様

### 操作別データベース影響一覧

データベース操作なし（セッション変数のみ使用）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| err_captcha | 認証エラー | CAPTCHA入力が一致しない | エラーメッセージ表示、フォーム再表示 |
| - | 空入力 | CAPTCHA未入力 | err_captchaエラーとして処理 |

### リトライ仕様

- CAPTCHA認証失敗時はフォームが再表示される
- 新しいCAPTCHA画像が生成される
- 無制限にリトライ可能（ログイン画面は試行回数制限あり）

## トランザクション仕様

データベース操作を伴わないため、トランザクション管理は不要。

## パフォーマンス要件

- CAPTCHA画像生成: 100ms以内
- 検証処理: 1ms以内
- 画像サイズ: 約5KB以下

## セキュリティ考慮事項

1. **OCR対策**: ノイズ効果オプション（sketch、foreground/background lines）
2. **連続文字回避**: 同一文字が連続しないようループで制御
3. **キャッシュ無効化**: Cache-Control: no-cache、Pragma: no-cache、Expires: -1
4. **セッション依存**: CAPTCHAコードはセッションに保存、セッション切れで無効
5. **大文字小文字無視**: ユーザビリティ向上のため大文字小文字を区別しない

## 備考

- ASP Security Image Generator v3.0（2006年版）をベースに実装
- ライセンス: Common Public License
- フォントマップは独自形式でハードコードされている
- カラーマップは10種類の配色パターンからランダム選択
- NoiseEffectは0〜4の5種類（0: なし、1: sketch、2: 前景線、3: 背景線、4: 1と3の組み合わせ）

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

CAPTCHA生成に使用するデータ構造を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | captcha.asp | `asp/includes/captcha.asp` 22-40行目 | FontMap配列（フォント定義） |
| 1-2 | captcha.asp | `asp/includes/captcha.asp` 44-57行目 | ColorMap配列（配色定義） |
| 1-3 | captcha.asp | `asp/includes/captcha.asp` 65行目 | Bitmap配列（25x62の描画キャンバス） |

**読解のコツ**: FontMapは各文字のピクセルパターンを定義。*はヌルピクセル、#はテキストピクセル、&は行参照。

#### Step 2: エントリーポイントを理解する

CAPTCHA画像生成の起点を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | captcha.asp | `asp/includes/captcha.asp` 404-413行目 | メイン処理 |

**主要処理フロー**:
1. **406行目**: `CreateGUID(CodeLength)` - 4文字のコード生成
2. **407行目**: `Session("CAPTCHA") = secureCode` - セッションに保存
3. **408行目**: `PrepareBitmap(secureCode)` - ビットマップ準備
4. **409-411行目**: ノイズ効果適用（オプション）
5. **412行目**: `SendBitmap()` - 画像出力

#### Step 3: コード生成ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | captcha.asp | `asp/includes/captcha.asp` 75-87行目 | CreateGUID関数 |

**ポイント**: strValid = "ABCDEF1234567890"から4文字をランダム選択。連続同一文字を回避。

#### Step 4: ビットマップ生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | captcha.asp | `asp/includes/captcha.asp` 170-227行目 | PrepareBitmap関数 |
| 4-2 | captcha.asp | `asp/includes/captcha.asp` 111-168行目 | WriteCanvas関数 |
| 4-3 | captcha.asp | `asp/includes/captcha.asp` 362-401行目 | SendBitmap関数 |

#### Step 5: 検証処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | mailPage.asp | `mailPage.asp` 22-24行目 | CAPTCHA検証の実装例 |
| 5-2 | bs_login.asp | `asp/bs_login.asp` | ログイン画面での検証例 |

### プログラム呼び出し階層図

```
captcha.asp（メイン処理）
    │
    ├─ CreateGUID(CodeLength=4)
    │      └─ Randomize(Timer) ... 乱数初期化
    │
    ├─ Session("CAPTCHA") = secureCode ... セッション保存
    │
    ├─ PrepareBitmap(secureCode)
    │      │
    │      ├─ GetCharMap() ... フォントマップ取得
    │      │
    │      ├─ RndInterval() ... カラー選択
    │      │
    │      ├─ AddNoise() ... ノイズ効果（オプション）
    │      │      └─ DrawLine() ... 線描画
    │      │
    │      └─ WriteCanvas() ... 文字描画
    │
    └─ SendBitmap()
           │
           ├─ FormatHex() ... 16進数フォーマット
           │
           └─ SendHex() ... バイナリ出力
```

### データフロー図

```
[入力]                      [処理]                           [出力]

captcha.aspアクセス ───────> CreateGUID() ─────────────> secureCode
                            (4文字生成)                  (例: "A1B2")
                                 │
                                 v
                            Session("CAPTCHA") ────────> セッション保存
                                 │
                                 v
FontMap配列 ───────────────> PrepareBitmap() ──────────> Bitmap配列
ColorMap配列 ─────────────────> │                        (25x62)
                                 │
                                 v
                            WriteCanvas() ─────────────> 文字描画済み
                            (各文字をループ)               Bitmap
                                 │
                                 v
                            AddNoise() ────────────────> ノイズ追加
                            (オプション)
                                 │
                                 v
                            SendBitmap() ──────────────> HTTPレスポンス
                            (BMP形式)                     (image/bmp)

[検証時]

Request.Form("CAPTCHA") ───> LCase() ──────────────────> 小文字変換
                                 │
Session("CAPTCHA") ────────> LCase() ──────────────────> 小文字変換
                                 │
                                 v
                            Left(input, 4) ────────────> 先頭4文字
                                 │
                                 v
                            比較 ──────────────────────> 一致/不一致
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| captcha.asp | `asp/includes/captcha.asp` | ソース | CAPTCHA画像生成 |
| bs_login.asp | `asp/bs_login.asp` | ソース | バックサイトログイン（CAPTCHA使用） |
| ad_login.asp | `asp/ad_login.asp` | ソース | 管理者ログイン（CAPTCHA使用） |
| mailPage.asp | `mailPage.asp` | ソース | ページメール送信（CAPTCHA使用） |
| process_forgotPW.asp | `asp/process_forgotPW.asp` | ソース | パスワード忘れ処理（CAPTCHA使用） |

### 利用例

```asp
' フォームでCAPTCHA画像を表示
<img src="includes/captcha.asp" alt="CAPTCHA" />
<input type="text" name="CAPTCHA" maxlength="4" />

' 送信時の検証
<%
If LCase(session("CAPTCHA")) <> LCase(Left(Request.Form("CAPTCHA"),4)) Then
    message.AddError("err_captcha")
End If
%>
```
