제5장

출처 추적

콘텐츠의 생성, 편집, 배포 이력을 투명하게 기록

출처(Provenance)란 무엇인가

출처(provenance)는 디지털 콘텐츠의 전체 생명주기를 추적합니다. 생성, 편집, 배포, 소유권 이전 등 모든 이력을 기록하여 콘텐츠의 진위성과 신뢰성을 입증합니다.

ℹ️ 출처 추적이 중요한 이유
• 신뢰성: 콘텐츠가 믿을 수 있는 출처에서 왔는지 확인
• 무결성: 콘텐츠가 변조되지 않았는지 검증
• 책임성: 생성 및 편집에 대한 책임 추적
• 투명성: AI 사용 여부 및 편집 이력 공개
• 법적 증거: 분쟁 시 콘텐츠 이력 증명

출처 데이터 모델

WIA-AI-017은 포괄적인 출처 추적을 위한 표준 데이터 모델을 정의합니다.

// WIA-AI-017 출처 데이터 구조
interface ProvenanceRecord {
    recordId: string;                     // 고유 ID
    version: string;                      // 표준 버전

    // 콘텐츠 참조
    asset: {
        id: string;                       // 자산 ID
        type: 'image' | 'video' | 'audio' | 'text' | 'mixed';
        hash: string;                     // SHA-256 해시
        format: string;                   // MIME 타입
    };

    // 생성 정보
    creation: {
        timestamp: string;                // ISO 8601
        creator: {
            type: 'human' | 'ai' | 'hybrid';
            name?: string;                // 생성자 이름
            organization?: string;        // 조직
            aiModel?: string;             // AI 모델명
            aiVersion?: string;           // 모델 버전
        };
        method: string;                   // 생성 방법
        software: {
            name: string;                 // 소프트웨어명
            version: string;              // 버전
        };
    };

    // 편집 이력
    edits: Array<{
        editId: string;                   // 편집 ID
        timestamp: string;                // 편집 시각
        editor: {
            type: 'human' | 'ai' | 'automated';
            name?: string;
        };
        operation: string;                // 편집 작업명
        description: string;              // 설명
        aiAssisted: boolean;              // AI 도움 여부
        previousHash: string;             // 이전 버전 해시
        currentHash: string;              // 현재 버전 해시
    }>;

    // 디지털 서명
    signatures: Array<{
        signerId: string;                 // 서명자 ID
        algorithm: string;                // 서명 알고리즘
        value: string;                    // 서명 값
        certificate: string;              // X.509 인증서
        timestamp: string;                // 서명 시각
    }>;
}

// 사용 예제
const provenance: ProvenanceRecord = {
    recordId: 'prov-' + crypto.randomUUID(),
    version: '1.0',
    asset: {
        id: 'asset-' + crypto.randomUUID(),
        type: 'image',
        hash: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08',
        format: 'image/jpeg'
    },
    creation: {
        timestamp: '2025-01-15T10:30:00Z',
        creator: {
            type: 'hybrid',
            name: 'Jane Doe',
            aiModel: 'DALL-E-3',
            aiVersion: '1.0'
        },
        method: 'ai-generated-then-edited',
        software: {
            name: 'Adobe Photoshop',
            version: '2025.1'
        }
    },
    edits: [{
        editId: 'edit-001',
        timestamp: '2025-01-15T11:00:00Z',
        editor: { type: 'human', name: 'Jane Doe' },
        operation: 'color-correction',
        description: '색상 보정 및 밝기 조정',
        aiAssisted: true,
        previousHash: 'prev_hash',
        currentHash: 'curr_hash'
    }],
    signatures: []
};

블록체인 기반 출처 추적

블록체인은 변조 불가능한 출처 기록을 제공합니다. 분산 원장에 기록된 정보는 소급 변경이 불가능합니다.

// Solidity 스마트 컨트랙트
pragma solidity ^0.8.0;

contract ContentProvenance {
    struct ProvenanceEntry {
        string assetId;           // 자산 ID
        string contentHash;       // 콘텐츠 해시
        string recordHash;        // 출처 레코드 해시
        address creator;          // 생성자 주소
        uint256 timestamp;        // 타임스탬프
        string recordURI;         // IPFS URI
    }

    mapping(string => ProvenanceEntry) public provenanceRecords;

    event ProvenanceRegistered(
        string indexed assetId,
        address indexed creator,
        uint256 timestamp
    );

    // 출처 등록
    function registerProvenance(
        string memory assetId,
        string memory contentHash,
        string memory recordHash,
        string memory recordURI
    ) public {
        require(
            provenanceRecords[assetId].timestamp == 0,
            "이미 등록된 자산입니다"
        );

        provenanceRecords[assetId] = ProvenanceEntry({
            assetId: assetId,
            contentHash: contentHash,
            recordHash: recordHash,
            creator: msg.sender,
            timestamp: block.timestamp,
            recordURI: recordURI
        });

        emit ProvenanceRegistered(assetId, msg.sender, block.timestamp);
    }
}

IPFS 기반 분산 저장

IPFS는 콘텐츠 주소 지정 가능한 분산 파일 시스템으로, 출처 데이터의 영구적이고 검증 가능한 저장을 제공합니다.

// IPFS를 사용한 출처 저장
import { create } from 'ipfs-http-client';

class IPFSProvenanceStorage {
    private ipfs: any;

    constructor(apiUrl: string = 'https://ipfs.infura.io:5001') {
        this.ipfs = create({ url: apiUrl });
    }

    // 출처 레코드를 IPFS에 저장
    async storeProvenanceRecord(
        record: ProvenanceRecord
    ): Promise {
        const recordJson = JSON.stringify(record, null, 2);
        const { cid } = await this.ipfs.add(recordJson, { pin: true });

        console.log(`✅ 출처 레코드 저장: ${cid}`);
        return cid.toString();
    }

    // IPFS에서 출처 레코드 검색
    async retrieveProvenanceRecord(cid: string): Promise {
        const chunks: Uint8Array[] = [];

        for await (const chunk of this.ipfs.cat(cid)) {
            chunks.push(chunk);
        }

        const data = Buffer.concat(chunks);
        return JSON.parse(data.toString('utf-8'));
    }

    // 버전 DAG 생성
    async createVersionDAG(
        versions: Array<{
            content: Buffer;
            metadata: any;
            parent?: string;
        }>
    ): Promise {
        let previousCid: string | undefined;

        for (const version of versions) {
            const versionObject = {
                content: await this.ipfs.add(version.content),
                metadata: version.metadata,
                parent: version.parent || previousCid,
                timestamp: new Date().toISOString()
            };

            const { cid } = await this.ipfs.dag.put(versionObject);
            previousCid = cid.toString();

            console.log(`📦 버전 저장: ${previousCid}`);
        }

        return previousCid!;
    }
}

출처 체인 검증

출처 데이터의 무결성을 검증하고 감사 추적을 제공합니다.

// 출처 검증 시스템
class ProvenanceVerifier {
    // 전체 출처 체인 검증
    async verifyProvenanceChain(
        record: ProvenanceRecord,
        currentContentHash: string
    ): Promise<{
        valid: boolean;
        errors: string[];
        warnings: string[];
    }> {
        const errors: string[] = [];
        const warnings: string[] = [];

        // 1. 생성 정보 검증
        if (!record.creation.timestamp) {
            errors.push('생성 타임스탬프 누락');
        }

        // 2. 편집 체인 검증
        let expectedHash = record.asset.hash;

        for (let i = 0; i < record.edits.length; i++) {
            const edit = record.edits[i];

            // 이전 해시 일치 확인
            if (edit.previousHash !== expectedHash) {
                errors.push(
                    `편집 ${i + 1}: 이전 해시 불일치`
                );
            }

            // 타임스탬프 순서 확인
            if (i > 0) {
                const prevTime = new Date(record.edits[i - 1].timestamp);
                const currTime = new Date(edit.timestamp);

                if (currTime < prevTime) {
                    errors.push(`편집 ${i + 1}: 타임스탬프 순서 오류`);
                }
            }

            expectedHash = edit.currentHash;
        }

        // 3. 최종 해시 검증
        if (record.edits.length > 0) {
            const lastEdit = record.edits[record.edits.length - 1];
            if (lastEdit.currentHash !== currentContentHash) {
                errors.push('최종 콘텐츠 해시 불일치');
            }
        }

        return {
            valid: errors.length === 0,
            errors,
            warnings
        };
    }

    // 감사 리포트 생성
    generateAuditReport(
        record: ProvenanceRecord,
        verificationResult: any
    ): string {
        const lines: string[] = [];

        lines.push('='.repeat(60));
        lines.push('출처 감사 리포트');
        lines.push('='.repeat(60));
        lines.push('');
        lines.push(`자산 ID: ${record.asset.id}`);
        lines.push(`생성자: ${record.creation.creator.name || 'Unknown'}`);
        lines.push(`편집 이력: ${record.edits.length}건`);
        lines.push('');
        lines.push(`검증 상태: ${verificationResult.valid ? '✅ 유효' : '❌ 무효'}`);

        return lines.join('\n');
    }
}

타임스탬프 서비스

신뢰할 수 있는 타임스탬프는 출처 기록의 시간적 순서를 보장합니다.

타임스탬프 방식 신뢰도 비용 용도
로컬 시스템 시간 낮음 무료 개발/테스트
NTP 서버 중간 무료 일반 응용
RFC 3161 TSA 높음 유료 법적 증거
블록체인 매우 높음 가스비 영구 기록

연합 학습 기반 출처 추적

개인정보 보호를 유지하면서도 분산 출처 추적이 가능합니다.

// 연합 학습 기반 출처 시스템
class FederatedProvenanceTracker {
    // 로컬에서 출처 레코드 생성
    createLocalRecord(
        assetId: string,
        operation: string
    ): ProvenanceRecord {
        // 민감한 정보는 로컬에만 보관
        const localRecord: ProvenanceRecord = {
            recordId: crypto.randomUUID(),
            version: '1.0',
            asset: {
                id: assetId,
                type: 'image',
                hash: '',  // 로컬 계산
                format: 'image/jpeg'
            },
            creation: {
                timestamp: new Date().toISOString(),
                creator: { type: 'human' },
                method: 'manual',
                software: { name: 'LocalApp', version: '1.0' }
            },
            edits: [],
            signatures: []
        };

        return localRecord;
    }

    // 집계 가능한 메타데이터만 공유
    async shareAggregatedMetadata(
        record: ProvenanceRecord
    ): Promise {
        // 개인 식별 정보 제거
        return {
            assetType: record.asset.type,
            creatorType: record.creation.creator.type,
            editCount: record.edits.length,
            timestamp: record.creation.timestamp
        };
    }
}

메타데이터 표준화

여러 시스템 간 상호운용성을 위한 표준 메타데이터 형식이 필요합니다.

// XMP, EXIF, IPTC 통합
class UnifiedMetadataManager {
    // 모든 메타데이터를 통합 형식으로 변환
    async extractAllMetadata(filePath: string): Promise {
        const exiftool = await import('exiftool-vendored').then(m => m.exiftool);

        // EXIF, XMP, IPTC 모두 읽기
        const metadata = await exiftool.read(filePath);

        return {
            exif: {
                make: metadata.Make,
                model: metadata.Model,
                dateTime: metadata.DateTimeOriginal
            },
            xmp: {
                creator: metadata.Creator,
                rights: metadata.Rights
            },
            iptc: {
                caption: metadata.Caption,
                keywords: metadata.Keywords
            },
            custom: {
                // WIA-AI-017 확장 필드
                aiGenerated: metadata.AIGenerated,
                provenanceURI: metadata.ProvenanceURI
            }
        };
    }

    // 통합 메타데이터 쓰기
    async writeUnifiedMetadata(
        filePath: string,
        metadata: any
    ): Promise {
        const exiftool = await import('exiftool-vendored').then(m => m.exiftool);

        await exiftool.write(filePath, {
            Creator: metadata.xmp.creator,
            Rights: metadata.xmp.rights,
            'Keywords': metadata.iptc.keywords,
            // 커스텀 필드
            'AIGenerated': metadata.custom.aiGenerated,
            'ProvenanceURI': metadata.custom.provenanceURI
        });

        console.log('✅ 메타데이터 작성 완료');
    }
}

크로스 플랫폼 출처 추적

여러 플랫폼과 서비스 간에 출처 정보를 전파합니다.

// 크로스 플랫폼 출처 전파
class CrossPlatformProvenancePropagator {
    // 소셜 미디어 플랫폼에 출처 정보 삽입
    async embedProvenanceForSocialMedia(
        imageBuffer: Buffer,
        provenance: ProvenanceRecord,
        platform: 'twitter' | 'facebook' | 'instagram'
    ): Promise {
        // 플랫폼별 메타데이터 정책 고려
        const platformPolicies = {
            twitter: { preservesEXIF: false, preservesIPTC: true },
            facebook: { preservesEXIF: true, preservesIPTC: false },
            instagram: { preservesEXIF: true, preservesIPTC: false }
        };

        const policy = platformPolicies[platform];

        if (policy.preservesIPTC) {
            // IPTC 메타데이터에 출처 URL 삽입
            // (구현 생략)
        } else {
            // 이미지에 스테가노그래피 워터마크 삽입
            // (구현 생략)
        }

        return imageBuffer;
    }
}
✅ 출처 추적 모범 사례
• 생성 시점부터 출처 기록 시작
• 모든 편집에 대해 이전 버전 해시 포함
• 블록체인으로 변조 방지 보장
• IPFS로 분산 저장 및 영구 보존
• 디지털 서명으로 책임성 확보
• 정기적인 감사 및 검증 수행

📌 요약

📝 복습 문제

  1. 디지털 콘텐츠에서 출처 추적이 중요한 이유를 설명하십시오.
  2. WIA-AI-017 출처 데이터 모델의 주요 구성 요소는 무엇입니까?
  3. 블록체인이 출처 추적에 적합한 이유는 무엇입니까?
  4. 스마트 컨트랙트로 출처를 관리할 때의 장점을 설명하십시오.
  5. IPFS의 콘텐츠 주소 지정(content addressing)이란 무엇입니까?
  6. 출처 검증 시 확인해야 할 핵심 사항은 무엇입니까?
  7. 연합 학습 기반 출처 추적의 장점은 무엇입니까?
  8. 크로스 플랫폼 출처 전파가 어려운 이유를 설명하십시오.

弘益人間 (홍익인간) · 널리 인간을 이롭게 하라