🏦 金融・高セキュリティ向けネットワーク設計 - PCI DSS準拠

概要

金融業界では、顧客データ保護と規制遵守が最重要課題です。本記事では、PCI DSS、SOX法、GDPR等の国際基準に準拠した高セキュリティネットワーク設計パターン、HSM連携、暗号化実装について詳しく解説します。

金融業界のセキュリティ要件

主要なコンプライアンス規制

PCI DSS(Payment Card Industry Data Security Standard)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
PCI_DSS_Requirements:
  1_Firewall_Configuration:
    - カード保持者データ保護
    - ネットワーク境界の明確化
    - Default設定の変更
  
  2_Security_Parameters:
    - システムパスワード変更
    - ベンダー提供のセキュリティ設定
    - 強力な認証システム
  
  3_Stored_Data_Protection:
    - カード保持者データ暗号化
    - 保存データの最小化
    - 適切なデータ廃棄
  
  4_Transmission_Encryption:
    - 公開ネットワーク上の暗号化
    - 強力な暗号方式使用
    - 暗号鍵管理

SOX法(サーベンス・オクスリー法)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
SOX_404_Requirements:
  Internal_Control:
    - 財務報告の信頼性
    - 内部統制の有効性
    - 経営者による評価・報告
  
  IT_General_Controls:
    - アクセス制御
    - プログラム変更管理
    - システム運用管理
    - データバックアップ

GDPR(EU一般データ保護規則)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
GDPR_Requirements:
  Data_Protection_Principles:
    - 合法性・公正性・透明性
    - 目的の限定
    - データの最小化
    - 正確性の確保
  
  Technical_Measures:
    - デフォルトによるデータ保護
    - 仮名化・暗号化
    - 継続的な機密性確保
    - データ可用性・復旧力

高セキュリティネットワーク設計

7層防御アーキテクチャ

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
VPC: financial-vpc (10.0.0.0/16)

Network_Layers:
  Layer_1_DMZ: 10.0.1.0/24
    Purpose: WAF / Cloud Armor
    Security: Internet境界防御
    Access: Public (制限付き)
  
  Layer_2_Proxy: 10.0.2.0/24  
    Purpose: Reverse Proxy / SSL終端
    Security: アプリケーション保護
    Access: DMZ経由のみ
  
  Layer_3_Application: 10.0.3.0/24
    Purpose: Webアプリケーション
    Security: アプリケーション認証
    Access: Proxy経由のみ
  
  Layer_4_API: 10.0.4.0/24
    Purpose: APIゲートウェイ
    Security: API認証・認可
    Access: Application経由のみ
  
  Layer_5_Core: 10.0.5.0/24
    Purpose: コアバンキングシステム
    Security: 最高機密処理
    Access: API経由のみ
  
  Layer_6_Database: 10.0.6.0/24
    Purpose: 暗号化データベース
    Security: TDE + Column暗号化
    Access: Core経由のみ
  
  Layer_7_HSM: 10.0.7.0/24
    Purpose: 暗号鍵管理
    Security: ハードウェアセキュリティ
    Access: Core経由のみ

ファイアウォール設定(Defense in Depth)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# Layer 1: Internet → DMZ (HTTPS only)
gcloud compute firewall-rules create allow-dmz-https \
    --direction=INGRESS \
    --priority=1000 \
    --source-ranges=0.0.0.0/0 \
    --target-tags=dmz \
    --allow=tcp:443 \
    --enable-logging

# HTTP完全ブロック
gcloud compute firewall-rules create deny-dmz-http \
    --direction=INGRESS \
    --priority=999 \
    --source-ranges=0.0.0.0/0 \
    --target-tags=dmz \
    --action=DENY \
    --rules=tcp:80

# Layer 2: DMZ → Proxy (認証済みのみ)
gcloud compute firewall-rules create allow-dmz-to-proxy \
    --direction=INGRESS \
    --priority=1000 \
    --source-tags=dmz \
    --target-tags=proxy \
    --allow=tcp:8443 \
    --enable-logging

# Layer 3: Proxy → Application
gcloud compute firewall-rules create allow-proxy-to-app \
    --direction=INGRESS \
    --priority=1000 \
    --source-tags=proxy \
    --target-tags=application \
    --allow=tcp:8080 \
    --enable-logging

# Layer 5: Core Banking (厳重制御)
gcloud compute firewall-rules create allow-api-to-core \
    --direction=INGRESS \
    --priority=1000 \
    --source-tags=api-gateway \
    --target-tags=core-banking \
    --allow=tcp:9443 \
    --enable-logging

# Layer 6: Database (Core Banking経由のみ)
gcloud compute firewall-rules create allow-core-to-db \
    --direction=INGRESS \
    --priority=1000 \
    --source-tags=core-banking \
    --target-tags=database \
    --allow=tcp:5432 \
    --enable-logging

# Layer 7: HSM (最高機密)
gcloud compute firewall-rules create allow-core-to-hsm \
    --direction=INGRESS \
    --priority=1000 \
    --source-tags=core-banking \
    --target-tags=hsm \
    --allow=tcp:443 \
    --enable-logging

# 全外部アクセス完全拒否
gcloud compute firewall-rules create deny-hsm-external \
    --direction=INGRESS \
    --priority=999 \
    --source-ranges=0.0.0.0/0 \
    --target-tags=hsm \
    --action=DENY \
    --rules=all

HSM(Hardware Security Module)統合

Cloud HSM設定

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# Cloud HSM クラスター作成
gcloud kms keyrings create financial-keyring \
    --location=asia-northeast1

gcloud kms keys create master-key \
    --location=asia-northeast1 \
    --keyring=financial-keyring \
    --purpose=encryption \
    --protection-level=hsm

# HSM専用VPCエンドポイント
gcloud compute addresses create hsm-endpoint \
    --subnet=hsm-subnet \
    --addresses=10.0.7.100

gcloud compute forwarding-rules create hsm-lb \
    --load-balancing-scheme=INTERNAL \
    --network=financial-vpc \
    --subnet=hsm-subnet \
    --address=hsm-endpoint \
    --ports=443

暗号鍵管理プロセス

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# 暗号鍵管理システム
from google.cloud import kms
from cryptography.fernet import Fernet
import secrets

class FinancialCrypto:
    def __init__(self):
        self.kms_client = kms.KeyManagementServiceClient()
        self.key_name = "projects/project-id/locations/asia-northeast1/keyRings/financial-keyring/cryptoKeys/master-key"
    
    def encrypt_sensitive_data(self, plaintext_data):
        """機密データ暗号化(HSM使用)"""
        
        # データ暗号化キー生成
        dek = Fernet.generate_key()
        
        # DEKをHSMで暗号化
        encrypt_request = {
            'name': self.key_name,
            'plaintext': dek
        }
        encrypt_response = self.kms_client.encrypt(encrypt_request)
        encrypted_dek = encrypt_response.ciphertext
        
        # データをDEKで暗号化
        f = Fernet(dek)
        encrypted_data = f.encrypt(plaintext_data.encode())
        
        return {
            'encrypted_data': encrypted_data,
            'encrypted_dek': encrypted_dek,
            'algorithm': 'AES-256-GCM',
            'hsm_key_version': encrypt_response.name
        }
    
    def decrypt_sensitive_data(self, encrypted_package):
        """機密データ復号化(HSM使用)"""
        
        # HSMでDEK復号化
        decrypt_request = {
            'name': self.key_name,
            'ciphertext': encrypted_package['encrypted_dek']
        }
        decrypt_response = self.kms_client.decrypt(decrypt_request)
        dek = decrypt_response.plaintext
        
        # データ復号化
        f = Fernet(dek)
        plaintext_data = f.decrypt(encrypted_package['encrypted_data'])
        
        return plaintext_data.decode()

    def rotate_master_key(self):
        """マスターキーローテーション"""
        
        # 新バージョン作成
        version_request = {
            'parent': self.key_name
        }
        new_version = self.kms_client.create_crypto_key_version(version_request)
        
        # 古いバージョンを無効化(段階的移行)
        # Production実装では段階的なデータ再暗号化が必要
        
        return new_version.name

データベース暗号化設計

TDE(Transparent Data Encryption)実装

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
-- Cloud SQL PostgreSQL暗号化設定
CREATE EXTENSION IF NOT EXISTS pgcrypto;

-- 暗号化テーブル作成
CREATE TABLE customer_data (
    id SERIAL PRIMARY KEY,
    account_number VARCHAR(20) NOT NULL,
    -- 個人識別情報暗号化
    customer_name_encrypted BYTEA,
    ssn_encrypted BYTEA,
    -- クレジットカード情報(PCI DSS準拠)
    card_number_encrypted BYTEA,
    card_expiry_encrypted BYTEA,
    -- メタデータ
    created_at TIMESTAMP DEFAULT NOW(),
    encryption_key_version VARCHAR(50),
    -- 検索用ハッシュ(可逆性なし)
    customer_name_hash VARCHAR(64),
    account_hash VARCHAR(64)
);

-- 暗号化関数
CREATE OR REPLACE FUNCTION encrypt_pii(
    plaintext TEXT,
    key_version TEXT
) RETURNS BYTEA AS $$
BEGIN
    -- HSM派生キーによる暗号化
    -- 実装では Cloud KMS API を使用
    RETURN pgp_sym_encrypt(plaintext, key_version);
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

-- 復号化関数(監査ログ付き)
CREATE OR REPLACE FUNCTION decrypt_pii(
    ciphertext BYTEA,
    key_version TEXT,
    access_reason TEXT
) RETURNS TEXT AS $$
BEGIN
    -- アクセス監査ログ記録
    INSERT INTO pii_access_log (
        accessed_at,
        user_id,
        table_name,
        reason,
        key_version
    ) VALUES (
        NOW(),
        current_user,
        TG_TABLE_NAME,
        access_reason,
        key_version
    );
    
    -- 復号化実行
    RETURN pgp_sym_decrypt(ciphertext, key_version);
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

Column Level暗号化

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# アプリケーションレベル暗号化
import hashlib
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import os

class ColumnEncryption:
    def __init__(self, hsm_client):
        self.hsm_client = hsm_client
    
    def encrypt_column(self, plaintext, column_key_id):
        """カラムレベル暗号化"""
        
        # HSMから列暗号化キー取得
        column_key = self.hsm_client.get_data_key(column_key_id)
        
        # AES-GCM暗号化
        iv = os.urandom(12)  # 96-bit IV for GCM
        cipher = Cipher(
            algorithms.AES(column_key),
            modes.GCM(iv),
            backend=default_backend()
        )
        encryptor = cipher.encryptor()
        
        # 暗号化実行
        ciphertext = encryptor.update(plaintext.encode())
        encryptor.finalize()
        
        # 認証タグ付与
        auth_tag = encryptor.tag
        
        return {
            'ciphertext': ciphertext,
            'iv': iv,
            'auth_tag': auth_tag,
            'key_version': column_key_id
        }
    
    def create_search_hash(self, plaintext, salt):
        """検索可能ハッシュ生成(非可逆)"""
        
        # PBKDF2によるハッシュ化
        hash_value = hashlib.pbkdf2_hmac(
            'sha256',
            plaintext.encode(),
            salt,
            100000  # iterations
        )
        
        return hash_value.hex()

ネットワーク監視・監査

リアルタイム脅威検知

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# Cloud Functions セキュリティ監視
import json
import base64
from google.cloud import logging
from google.cloud import monitoring_v3
from google.cloud import securitycenter

def financial_security_monitor(event, context):
    """金融システムセキュリティ監視"""
    
    # ログデータ取得
    log_data = json.loads(base64.b64decode(event['data']).decode())
    
    # 脅威検知パターン
    threats = {
        'brute_force': detect_brute_force_attack(log_data),
        'data_exfiltration': detect_data_exfiltration(log_data),
        'privilege_escalation': detect_privilege_escalation(log_data),
        'insider_threat': detect_insider_threat(log_data)
    }
    
    # 脅威対応
    for threat_type, detected in threats.items():
        if detected:
            handle_security_incident(threat_type, log_data)

def detect_brute_force_attack(log_data):
    """ブルートフォース攻撃検知"""
    
    # 失敗ログイン試行の頻度分析
    if log_data.get('severity') == 'WARNING':
        if 'authentication failed' in log_data.get('textPayload', ''):
            source_ip = extract_source_ip(log_data)
            
            # 過去5分間の失敗回数確認
            failure_count = count_recent_failures(source_ip, minutes=5)
            
            if failure_count > 10:
                return True
    
    return False

def detect_data_exfiltration(log_data):
    """データ流出検知"""
    
    # 大量データ転送の検知
    if 'bytes_sent' in log_data:
        bytes_sent = int(log_data['bytes_sent'])
        
        # 閾値超過(10MB以上)
        if bytes_sent > 10 * 1024 * 1024:
            
            # 通常時との比較
            baseline = get_transfer_baseline(log_data['user_id'])
            
            if bytes_sent > baseline * 5:  # 5倍超
                return True
    
    return False

def handle_security_incident(threat_type, log_data):
    """セキュリティインシデント対応"""
    
    # Security Command Center通知
    security_client = securitycenter.SecurityCenterClient()
    
    finding = {
        'name': f'financial-security-{threat_type}',
        'parent': 'organizations/ORG_ID/sources/SOURCE_ID',
        'resource_name': log_data.get('resource', 'unknown'),
        'category': threat_type.upper(),
        'state': 'ACTIVE',
        'event_time': log_data.get('timestamp')
    }
    
    security_client.create_finding(finding)
    
    # 自動対応実行
    if threat_type == 'brute_force':
        block_source_ip(extract_source_ip(log_data))
    elif threat_type == 'data_exfiltration':
        suspend_user_account(log_data['user_id'])

監査証跡(Audit Trail)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# Cloud Audit Logs 設定
apiVersion: v1
kind: ConfigMap
metadata:
  name: audit-policy
  namespace: kube-system
data:
  audit-policy.yaml: |
    rules:
    # 金融データアクセス(詳細記録)
    - level: RequestResponse
      resources:
      - group: ""
        resources: ["secrets"]
        resourceNames: ["financial-data", "customer-pii"]
      
    # HSM操作(完全記録)
    - level: RequestResponse
      resources:
      - group: "kms.gcp"
        resources: ["cryptokeys", "keyrings"]
      
    # 権限変更(完全記録)
    - level: RequestResponse
      resources:
      - group: "rbac.authorization.k8s.io"
        resources: ["roles", "rolebindings"]
      
    # ログイン・認証(メタデータ記録)
    - level: Metadata
      resources:
      - group: "authentication.k8s.io"
        resources: ["tokenreviews"]

コンプライアンス自動チェック

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
# コンプライアンス自動監査
from google.cloud import asset_v1
from google.cloud import securitycenter
from google.cloud import storage
import datetime

class ComplianceAuditor:
    def __init__(self):
        self.asset_client = asset_v1.AssetServiceClient()
        self.security_client = securitycenter.SecurityCenterClient()
    
    def audit_pci_dss_compliance(self):
        """PCI DSS準拠性監査"""
        
        compliance_checks = {
            'firewall_rules': self.check_firewall_configuration(),
            'encryption_at_rest': self.check_encryption_at_rest(),
            'access_controls': self.check_access_controls(),
            'vulnerability_management': self.check_vulnerability_mgmt(),
            'network_monitoring': self.check_network_monitoring()
        }
        
        # コンプライアンス報告書生成
        report = self.generate_compliance_report(compliance_checks)
        
        return report
    
    def check_firewall_configuration(self):
        """ファイアウォール設定監査"""
        
        # すべてのファイアウォールルール取得
        request = asset_v1.ListAssetsRequest(
            parent="projects/project-id",
            asset_types=["compute.googleapis.com/Firewall"],
            content_type=asset_v1.ContentType.RESOURCE
        )
        
        assets = self.asset_client.list_assets(request=request)
        
        violations = []
        for asset in assets:
            rule = asset.resource.data
            
            # PCI DSS違反チェック
            if self.is_insecure_firewall_rule(rule):
                violations.append({
                    'resource': asset.name,
                    'violation': 'Insecure firewall configuration',
                    'severity': 'HIGH'
                })
        
        return {
            'status': 'PASS' if not violations else 'FAIL',
            'violations': violations
        }
    
    def check_encryption_at_rest(self):
        """保存時暗号化監査"""
        
        # Cloud SQL インスタンス確認
        sql_instances = self.get_sql_instances()
        
        violations = []
        for instance in sql_instances:
            if not instance.get('diskEncryptionConfiguration', {}).get('kmsKeyName'):
                violations.append({
                    'resource': instance['name'],
                    'violation': 'Database not encrypted with customer-managed key',
                    'severity': 'CRITICAL'
                })
        
        return {
            'status': 'PASS' if not violations else 'FAIL', 
            'violations': violations
        }
    
    def generate_compliance_report(self, checks):
        """コンプライアンス報告書生成"""
        
        report = {
            'audit_date': datetime.datetime.now().isoformat(),
            'overall_status': 'COMPLIANT',
            'checks': checks,
            'recommendations': []
        }
        
        # 総合判定
        for check_name, result in checks.items():
            if result['status'] == 'FAIL':
                report['overall_status'] = 'NON_COMPLIANT'
                
                # 修正推奨事項追加
                for violation in result['violations']:
                    recommendation = self.get_remediation_advice(
                        check_name, 
                        violation
                    )
                    report['recommendations'].append(recommendation)
        
        # GCS に保存(監査証跡)
        self.save_audit_report(report)
        
        return report

事業継続計画(BCP)

災害復旧設計

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Multi-Region DR 設定
Primary_Region: asia-northeast1
DR_Region: asia-northeast2

Recovery_Objectives:
  RTO: 4 hours  # 営業再開目標時間
  RPO: 15 minutes  # データ損失許容時間

DR_Architecture:
  Database_Replication:
    Type: Synchronous replication
    Lag: < 1 second
    Failover: Automatic
  
  Application_Deployment:
    Type: Active-Passive
    Warm_Standby: Yes
    Failover: Manual approval required
  
  Network_Configuration:
    VPC_Peering: Cross-region
    Load_Balancer: Global
    DNS_Failover: Health check based

バックアップ暗号化

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 暗号化バックアップ作成
gcloud sql backups create \
    --instance=financial-db-primary \
    --location=asia-northeast1 \
    --type=ON_DEMAND

# Cross-region encrypted copy
gcloud storage cp gs://financial-backups/backup.sql \
    gs://financial-dr-backups/backup.sql \
    --encryption-key=projects/project-id/locations/asia-northeast1/keyRings/backup-keyring/cryptoKeys/backup-key

まとめ

金融業界向け高セキュリティネットワーク設計の要点:

多層防御アーキテクチャ:

  • 7層セキュリティ境界: DMZ → Application → Database → HSM
  • 完全分離: レイヤー間の厳格なアクセス制御
  • ゼロトラスト: 全通信の認証・認可

暗号化の徹底:

  • HSM活用: ハードウェアベースの鍵管理
  • 多重暗号化: Transport + Application + Database
  • 鍵ローテーション: 定期的な暗号鍵更新

コンプライアンス対応:

  • PCI DSS Level 1: カード情報完全保護
  • SOX法: 財務システム統制
  • 監査証跡: 全操作の完全記録

適切な実装により、最高レベルのセキュリティと規制要件への完全準拠を両立できます。


📅 作成日: 2025年09月09日

参考リンク:

技術ネタ、趣味や備忘録などを書いているブログです
Hugo で構築されています。
テーマ StackJimmy によって設計されています。