MD5 暗号化

MD5 ハッシュ暗号化ツール

ツール概要:MD5 ハッシュ暗号化ツール

MD5(Message Digest Algorithm 5)は、任意の長さの入力データから128ビット(32文字の16進数)のハッシュ値を生成する暗号学的ハッシュ関数です。データの整合性検証、パスワードハッシュ化、キャッシュキー生成などの用途で広く使用されています。

MD5 ハッシュ暗号化ツールとは?

MD5 ハッシュ暗号化ツールはエンコード/デコードやチェックサム生成に対応します。

使い方

  1. 内容を貼り付けるかテキストを入力します。
  2. エンコード/ハッシュ方式を選択します。
  3. 結果をコピーします。

よくある利用シーン

  • 署名や整合性チェック
  • システム間の安全な転送
  • デバッグ時の簡易検証

❓ よくある質問

Q1: 同じ入力で結果が違う?
A: エンコードと不可視文字を確認してください。

Q2: 逆変換できる?
A: エンコードは可能、ハッシュは不可です。

Q3: 大きな入力は?
A: 小分け処理を推奨します。

✨ 主な機能

  • 🔐 高速ハッシュ化:テキストを瞬時にMD5ハッシュ値に変換
  • 🌐 多言語対応:日本語、中国語、英語などのUnicode文字をサポート
  • 📊 一意性保証:同じ入力に対して常に同じハッシュ値を生成
  • 📋 ワンクリックコピー:生成されたハッシュ値を直接コピー可能
  • リアルタイム生成:入力と同時にハッシュ値を表示

📖 使用例

テキストハッシュ化

入力テキスト:

こんにちは、世界!

MD5ハッシュ値:

b8c9d3f5e6a7b2c4d1e8f9a0b3c6d9e2

パスワードハッシュ化

入力パスワード:

MySecurePassword123!

MD5ハッシュ値:

5d41402abc4b2a76b9719d911017c592

ファイル名ハッシュ化

入力ファイル名:

重要な文書_2024年度.pdf

MD5ハッシュ値:

a1b2c3d4e5f6789012345678901234ab

🎯 応用シーン

1. データ整合性検証

ファイルやデータの整合性をチェック:

// ファイルのMD5チェックサム計算
const calculateFileMD5 = async (file) => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    
    reader.onload = async (event) => {
      try {
        const arrayBuffer = event.target.result;
        const hashBuffer = await crypto.subtle.digest('MD5', arrayBuffer);
        const hashArray = Array.from(new Uint8Array(hashBuffer));
        const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
        resolve(hashHex);
      } catch (error) {
        reject(error);
      }
    };
    
    reader.onerror = reject;
    reader.readAsArrayBuffer(file);
  });
};

// データ整合性検証システム
class DataIntegrityChecker {
  constructor() {
    this.checksums = new Map();
  }

  // データのチェックサムを記録
  recordChecksum(dataId, data) {
    const checksum = this.calculateMD5(data);
    this.checksums.set(dataId, checksum);
    return checksum;
  }

  // データの整合性を検証
  verifyIntegrity(dataId, currentData) {
    const originalChecksum = this.checksums.get(dataId);
    if (!originalChecksum) {
      return { valid: false, reason: 'チェックサムが記録されていません' };
    }

    const currentChecksum = this.calculateMD5(currentData);
    const isValid = originalChecksum === currentChecksum;

    return {
      valid: isValid,
      originalChecksum,
      currentChecksum,
      reason: isValid ? '整合性OK' : 'データが変更されています'
    };
  }

  calculateMD5(data) {
    // MD5計算の実装(実際の実装では crypto ライブラリを使用)
    return CryptoJS.MD5(data).toString();
  }
}

// 使用例
const integrityChecker = new DataIntegrityChecker();

// データの記録
const originalData = "重要なビジネスデータ";
const checksum = integrityChecker.recordChecksum('data001', originalData);
console.log('記録されたチェックサム:', checksum);

// 後でデータの整合性を確認
const currentData = "重要なビジネスデータ"; // 変更されていない
const verification = integrityChecker.verifyIntegrity('data001', currentData);
console.log('整合性検証結果:', verification);

2. キャッシュキー生成

効率的なキャッシュシステムの構築:

// キャッシュマネージャー
class CacheManager {
  constructor() {
    this.cache = new Map();
    this.maxSize = 1000;
  }

  // キャッシュキーの生成
  generateCacheKey(params) {
    // パラメータを文字列に変換
    const paramString = JSON.stringify(params, Object.keys(params).sort());
    
    // MD5ハッシュでキーを生成
    return CryptoJS.MD5(paramString).toString();
  }

  // データの取得(キャッシュ優先)
  async getData(params, fetchFunction) {
    const cacheKey = this.generateCacheKey(params);
    
    // キャッシュから確認
    if (this.cache.has(cacheKey)) {
      console.log('キャッシュヒット:', cacheKey);
      return this.cache.get(cacheKey);
    }

    // キャッシュにない場合は新しく取得
    console.log('キャッシュミス、データを取得:', cacheKey);
    const data = await fetchFunction(params);
    
    // キャッシュに保存
    this.setCache(cacheKey, data);
    
    return data;
  }

  // キャッシュに保存
  setCache(key, data) {
    // キャッシュサイズの制限
    if (this.cache.size >= this.maxSize) {
      const firstKey = this.cache.keys().next().value;
      this.cache.delete(firstKey);
    }

    this.cache.set(key, {
      data: data,
      timestamp: Date.now()
    });
  }

  // キャッシュのクリア
  clearCache() {
    this.cache.clear();
  }

  // 期限切れキャッシュの削除
  cleanExpiredCache(maxAge = 3600000) { // 1時間
    const now = Date.now();
    for (const [key, value] of this.cache.entries()) {
      if (now - value.timestamp > maxAge) {
        this.cache.delete(key);
      }
    }
  }
}

// API呼び出し例
const cacheManager = new CacheManager();

const fetchUserData = async (userId) => {
  const response = await fetch(`/api/users/${userId}`);
  return await response.json();
};

// キャッシュを使用したデータ取得
const getUserData = async (userId) => {
  return await cacheManager.getData(
    { endpoint: 'users', userId: userId },
    () => fetchUserData(userId)
  );
};

// 使用例
getUserData('user123').then(data => {
  console.log('ユーザーデータ:', data);
});

3. 重複データ検出

データベースやファイルシステムでの重複検出:

// 重複検出システム
class DuplicateDetector {
  constructor() {
    this.hashes = new Set();
    this.hashToData = new Map();
  }

  // データの追加と重複チェック
  addData(data, metadata = {}) {
    const hash = this.calculateMD5(data);
    
    if (this.hashes.has(hash)) {
      return {
        isDuplicate: true,
        hash: hash,
        existingData: this.hashToData.get(hash),
        message: '重複データが検出されました'
      };
    }

    // 新しいデータとして追加
    this.hashes.add(hash);
    this.hashToData.set(hash, {
      data: data,
      metadata: metadata,
      addedAt: new Date().toISOString()
    });

    return {
      isDuplicate: false,
      hash: hash,
      message: '新しいデータとして追加されました'
    };
  }

  // ファイル重複チェック
  async checkFileDuplicate(file) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      
      reader.onload = (event) => {
        try {
          const content = event.target.result;
          const hash = CryptoJS.MD5(content).toString();
          
          const result = this.addData(content, {
            fileName: file.name,
            fileSize: file.size,
            fileType: file.type,
            lastModified: file.lastModified
          });

          resolve({
            ...result,
            fileInfo: {
              name: file.name,
              size: file.size,
              type: file.type
            }
          });
        } catch (error) {
          reject(error);
        }
      };
      
      reader.onerror = reject;
      reader.readAsText(file);
    });
  }

  calculateMD5(data) {
    return CryptoJS.MD5(data).toString();
  }

  // 統計情報の取得
  getStatistics() {
    return {
      totalHashes: this.hashes.size,
      totalData: this.hashToData.size,
      memoryUsage: this.estimateMemoryUsage()
    };
  }

  estimateMemoryUsage() {
    let totalSize = 0;
    for (const [hash, data] of this.hashToData.entries()) {
      totalSize += hash.length * 2; // hash文字列
      totalSize += JSON.stringify(data).length * 2; // データ
    }
    return `${(totalSize / 1024).toFixed(2)} KB`;
  }

  // データのクリア
  clear() {
    this.hashes.clear();
    this.hashToData.clear();
  }
}

// 使用例
const duplicateDetector = new DuplicateDetector();

// テキストデータの重複チェック
const textData1 = "これは重要な文書です。";
const textData2 = "これは重要な文書です。"; // 同じ内容
const textData3 = "これは別の文書です。";

console.log(duplicateDetector.addData(textData1, { source: 'document1.txt' }));
console.log(duplicateDetector.addData(textData2, { source: 'document2.txt' })); // 重複検出
console.log(duplicateDetector.addData(textData3, { source: 'document3.txt' }));

// ファイルの重複チェック
const fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', async (event) => {
  const files = event.target.files;
  
  for (const file of files) {
    try {
      const result = await duplicateDetector.checkFileDuplicate(file);
      console.log(`ファイル ${file.name}:`, result);
    } catch (error) {
      console.error('ファイル処理エラー:', error);
    }
  }
});

4. セッション管理

Webアプリケーションでのセッション識別:

// セッション管理システム
class SessionManager {
  constructor() {
    this.sessions = new Map();
    this.sessionTimeout = 30 * 60 * 1000; // 30分
  }

  // セッションIDの生成
  generateSessionId(userInfo) {
    const timestamp = Date.now();
    const randomValue = Math.random().toString(36);
    const userAgent = navigator.userAgent;
    
    const sessionData = `${userInfo.userId}_${timestamp}_${randomValue}_${userAgent}`;
    return CryptoJS.MD5(sessionData).toString();
  }

  // セッションの作成
  createSession(userInfo) {
    const sessionId = this.generateSessionId(userInfo);
    
    const session = {
      id: sessionId,
      userId: userInfo.userId,
      userAgent: navigator.userAgent,
      ipAddress: userInfo.ipAddress || 'unknown',
      createdAt: new Date(),
      lastAccessAt: new Date(),
      isActive: true,
      data: {}
    };

    this.sessions.set(sessionId, session);
    
    // 自動期限切れの設定
    setTimeout(() => {
      this.expireSession(sessionId);
    }, this.sessionTimeout);

    return sessionId;
  }

  // セッションの取得
  getSession(sessionId) {
    const session = this.sessions.get(sessionId);
    
    if (session && session.isActive) {
      // 最終アクセス時刻を更新
      session.lastAccessAt = new Date();
      return session;
    }
    
    return null;
  }

  // セッションデータの更新
  updateSessionData(sessionId, data) {
    const session = this.getSession(sessionId);
    if (session) {
      session.data = { ...session.data, ...data };
      return true;
    }
    return false;
  }

  // セッションの無効化
  invalidateSession(sessionId) {
    const session = this.sessions.get(sessionId);
    if (session) {
      session.isActive = false;
      this.sessions.delete(sessionId);
      return true;
    }
    return false;
  }

  // セッションの期限切れ処理
  expireSession(sessionId) {
    const session = this.sessions.get(sessionId);
    if (session) {
      const now = new Date();
      const lastAccess = new Date(session.lastAccessAt);
      const timeDiff = now - lastAccess;

      if (timeDiff > this.sessionTimeout) {
        this.invalidateSession(sessionId);
        console.log(`セッション ${sessionId} が期限切れになりました`);
      }
    }
  }

  // アクティブセッションの取得
  getActiveSessions(userId) {
    const userSessions = [];
    
    for (const [sessionId, session] of this.sessions) {
      if (session.userId === userId && session.isActive) {
        userSessions.push({
          id: sessionId,
          createdAt: session.createdAt,
          lastAccessAt: session.lastAccessAt,
          userAgent: session.userAgent,
          ipAddress: session.ipAddress
        });
      }
    }
    
    return userSessions;
  }

  // セッション統計
  getSessionStatistics() {
    let activeCount = 0;
    let totalCount = this.sessions.size;
    
    for (const session of this.sessions.values()) {
      if (session.isActive) {
        activeCount++;
      }
    }

    return {
      total: totalCount,
      active: activeCount,
      inactive: totalCount - activeCount
    };
  }
}

// 使用例
const sessionManager = new SessionManager();

// ログイン時のセッション作成
const loginUser = (userCredentials) => {
  // ユーザー認証処理(省略)
  const userInfo = {
    userId: 'user123',
    username: 'tanaka@example.com',
    ipAddress: '192.168.1.100'
  };

  const sessionId = sessionManager.createSession(userInfo);
  
  // セッションIDをクッキーに保存
  document.cookie = `sessionId=${sessionId}; path=/; max-age=1800`; // 30分
  
  console.log('ログイン成功、セッションID:', sessionId);
  return sessionId;
};

// セッション確認
const checkSession = () => {
  const cookies = document.cookie.split(';');
  const sessionCookie = cookies.find(cookie => cookie.trim().startsWith('sessionId='));
  
  if (sessionCookie) {
    const sessionId = sessionCookie.split('=')[1];
    const session = sessionManager.getSession(sessionId);
    
    if (session) {
      console.log('有効なセッション:', session);
      return session;
    }
  }
  
  console.log('有効なセッションがありません');
  return null;
};

// ログアウト
const logoutUser = () => {
  const session = checkSession();
  if (session) {
    sessionManager.invalidateSession(session.id);
    document.cookie = 'sessionId=; path=/; max-age=0'; // クッキーを削除
    console.log('ログアウトしました');
  }
};

🔧 技術詳細

MD5アルゴリズム

MD5の基本的な特徴:

ハッシュ長: 128ビット(32文字の16進数)
ブロックサイズ: 512ビット
処理速度: 高速
衝突耐性: 低い(現在は非推奨)

セキュリティ考慮事項

MD5の制限と代替案:

// MD5の制限
const limitations = {
  collision: 'MD5は衝突攻撃に脆弱',
  preimage: '第一原像攻撃に対する耐性が低い',
  rainbow: 'レインボーテーブル攻撃が可能',
  recommendation: 'セキュリティが重要な用途では SHA-256 以上を推奨'
};

// より安全な代替案
const secureAlternatives = {
  'SHA-256': 'より強力なハッシュ関数',
  'SHA-3': '最新の標準ハッシュ関数',
  'bcrypt': 'パスワードハッシュ専用',
  'scrypt': 'メモリハード関数',
  'Argon2': '最新のパスワードハッシュ関数'
};

// パスワードハッシュの推奨実装
const hashPassword = async (password, salt) => {
  // MD5ではなくbcryptやArgon2を使用することを推奨
  const encoder = new TextEncoder();
  const data = encoder.encode(password + salt);
  const hashBuffer = await crypto.subtle.digest('SHA-256', data);
  const hashArray = Array.from(new Uint8Array(hashBuffer));
  return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
};

💡 使用のコツ

  • 用途の選択:セキュリティが重要でない用途(キャッシュキー、チェックサムなど)に限定
  • ソルトの使用:パスワードハッシュ化時は必ずソルトを使用
  • 代替案の検討:セキュリティが重要な場合はSHA-256以上を使用
  • 性能と安全性:用途に応じて適切なハッシュ関数を選択

⚠️ 注意事項

  • セキュリティ:MD5は暗号学的に安全ではないため、セキュリティが重要な用途には使用しない
  • 衝突攻撃:異なる入力から同じハッシュ値が生成される可能性がある
  • パスワード:パスワードのハッシュ化にはbcryptやArgon2を使用することを推奨
  • 用途限定:データ整合性チェックやキャッシュキー生成など、セキュリティが重要でない用途に限定

🚀 使い方

  1. テキスト入力:ハッシュ化したいテキストを入力ボックスに入力
  2. 自動生成:入力と同時にMD5ハッシュ値が自動的に生成される
  3. 結果確認:32文字の16進数ハッシュ値を確認
  4. コピー使用:「コピー」ボタンでハッシュ値をクリップボードにコピー
  5. 用途活用:キャッシュキー、チェックサム、重複検出などに活用

ヒント:このツールはクライアント側でローカル処理を行い、入力データをサーバーに送信しないため、プライバシーが保護されます。