Boost.UUID

認証ライブラリC++UUID識別子セキュリティユニークBoostランダム生成

認証ライブラリ

Boost.UUID

概要

Boost.UUIDはC++用のUUID(Universally Unique Identifier)生成ライブラリです。RFC 4122に準拠した128ビットの一意識別子を生成し、認証システムでのユーザーID、セッションID、APIキーなどの生成に広く使用されています。暗号学的に安全なランダム生成器を含む複数の生成方式をサポートし、分散システムでの一意性を保証します。2025年現在もBoostライブラリの一部として活発に開発が続けられています。

詳細

Boost.UUIDはC++アプリケーションでUUIDを生成・操作するための包括的なライブラリです。以下の主な特徴があります:

  • RFC準拠: RFC 4122およびRFC 9562に完全準拠したUUID生成
  • 複数の生成方式: ランダム、時間ベース、名前ベース、nil UUID等をサポート
  • 暗号学的安全性: crypto-secureな疑似乱数生成器による安全な識別子生成
  • ヘッダーオンリー: ビルド不要でインクルードするだけで使用可能
  • スレッドセーフ: マルチスレッド環境での安全な使用
  • 分散システム対応: 中央集権的な調整なしに一意性を保証

メリット・デメリット

メリット

  • RFC標準に準拠した信頼性の高いUUID生成
  • 暗号学的に安全な乱数生成による高いセキュリティ
  • ヘッダーオンリーライブラリで導入とビルドが簡単
  • 分散システムでの一意性保証により衝突リスクが極めて低い
  • 豊富な生成オプション(時間ベース、名前ベース等)
  • C++標準ライブラリとの良好な統合

デメリット

  • C++以外の言語では使用できない
  • Boostライブラリ全体の依存関係が必要な場合がある
  • UUIDのサイズ(128ビット)が連続する整数より大きい
  • 生成されるIDが予測不可能で人間には読みにくい
  • パフォーマンスが重要な場面では生成コストが考慮事項

参考ページ

書き方の例

基本的なUUID生成

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <iostream>

int main() {
    // ランダムUUID生成器
    boost::uuids::random_generator gen;
    
    // UUID生成
    boost::uuids::uuid id = gen();
    
    // 文字列として出力
    std::cout << "Generated UUID: " << id << std::endl;
    // 例: 67e55044-10b1-426f-9247-bb680e5fe0c8
    
    return 0;
}

各種UUID生成器の使用

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <iostream>
#include <string>

int main() {
    // 1. ランダムUUID(最も一般的)
    boost::uuids::random_generator random_gen;
    boost::uuids::uuid random_id = random_gen();
    std::cout << "Random UUID: " << random_id << std::endl;
    
    // 2. Nil UUID(すべてゼロ)
    boost::uuids::nil_generator nil_gen;
    boost::uuids::uuid nil_id = nil_gen();
    std::cout << "Nil UUID: " << nil_id << std::endl;
    
    // 3. 文字列からUUID生成
    boost::uuids::string_generator string_gen;
    boost::uuids::uuid string_id = string_gen("01234567-89ab-cdef-0123-456789abcdef");
    std::cout << "String UUID: " << string_id << std::endl;
    
    // 4. 名前ベースUUID(MD5ハッシュベース)
    boost::uuids::name_generator_md5 name_gen(boost::uuids::ns::dns());
    boost::uuids::uuid name_id = name_gen("example.com");
    std::cout << "Name-based UUID: " << name_id << std::endl;
    
    return 0;
}

認証システムでのユーザーID生成

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <unordered_map>
#include <string>
#include <iostream>

class UserManager {
private:
    boost::uuids::random_generator uuid_gen;
    std::unordered_map<std::string, std::string> users; // UUID -> username
    
public:
    std::string createUser(const std::string& username) {
        // 新しいユーザーIDを生成
        boost::uuids::uuid user_id = uuid_gen();
        std::string id_string = boost::uuids::to_string(user_id);
        
        // ユーザーを登録
        users[id_string] = username;
        
        std::cout << "Created user '" << username 
                  << "' with ID: " << id_string << std::endl;
        
        return id_string;
    }
    
    bool authenticateUser(const std::string& user_id) {
        return users.find(user_id) != users.end();
    }
    
    std::string getUsername(const std::string& user_id) {
        auto it = users.find(user_id);
        return (it != users.end()) ? it->second : "";
    }
};

int main() {
    UserManager manager;
    
    // ユーザー作成
    std::string alice_id = manager.createUser("alice");
    std::string bob_id = manager.createUser("bob");
    
    // 認証確認
    if (manager.authenticateUser(alice_id)) {
        std::cout << "Alice authenticated successfully" << std::endl;
    }
    
    return 0;
}

セッション管理システム

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <unordered_map>
#include <chrono>
#include <string>
#include <iostream>

struct Session {
    std::string user_id;
    std::chrono::steady_clock::time_point created_at;
    std::chrono::steady_clock::time_point expires_at;
    
    bool isValid() const {
        return std::chrono::steady_clock::now() < expires_at;
    }
};

class SessionManager {
private:
    boost::uuids::random_generator uuid_gen;
    std::unordered_map<std::string, Session> sessions;
    std::chrono::minutes session_duration{30}; // 30分のセッション期間
    
public:
    std::string createSession(const std::string& user_id) {
        // セッションIDを生成
        boost::uuids::uuid session_uuid = uuid_gen();
        std::string session_id = boost::uuids::to_string(session_uuid);
        
        // セッションを作成
        auto now = std::chrono::steady_clock::now();
        sessions[session_id] = {
            user_id,
            now,
            now + session_duration
        };
        
        std::cout << "Created session " << session_id 
                  << " for user " << user_id << std::endl;
        
        return session_id;
    }
    
    bool validateSession(const std::string& session_id) {
        auto it = sessions.find(session_id);
        if (it == sessions.end()) {
            return false;
        }
        
        if (!it->second.isValid()) {
            sessions.erase(it); // 期限切れセッションを削除
            return false;
        }
        
        return true;
    }
    
    std::string getUserFromSession(const std::string& session_id) {
        auto it = sessions.find(session_id);
        return (it != sessions.end() && it->second.isValid()) ? it->second.user_id : "";
    }
    
    void invalidateSession(const std::string& session_id) {
        sessions.erase(session_id);
        std::cout << "Session " << session_id << " invalidated" << std::endl;
    }
};

int main() {
    SessionManager session_mgr;
    
    // セッション作成
    std::string session = session_mgr.createSession("user123");
    
    // セッション検証
    if (session_mgr.validateSession(session)) {
        std::string user = session_mgr.getUserFromSession(session);
        std::cout << "Valid session for user: " << user << std::endl;
    }
    
    // セッション無効化
    session_mgr.invalidateSession(session);
    
    return 0;
}

APIキー生成システム

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <unordered_map>
#include <vector>
#include <string>
#include <iostream>

enum class APIKeyScope {
    READ_ONLY,
    READ_WRITE,
    ADMIN
};

struct APIKey {
    std::string key;
    std::string user_id;
    APIKeyScope scope;
    bool active;
    
    APIKey(const std::string& k, const std::string& uid, APIKeyScope s)
        : key(k), user_id(uid), scope(s), active(true) {}
};

class APIKeyManager {
private:
    boost::uuids::random_generator uuid_gen;
    std::unordered_map<std::string, APIKey> api_keys;
    
public:
    std::string generateAPIKey(const std::string& user_id, APIKeyScope scope) {
        // APIキーを生成(プレフィックス付き)
        boost::uuids::uuid key_uuid = uuid_gen();
        std::string api_key = "ak_" + boost::uuids::to_string(key_uuid);
        
        // APIキーを登録
        api_keys.emplace(api_key, APIKey(api_key, user_id, scope));
        
        std::cout << "Generated API key: " << api_key 
                  << " for user: " << user_id << std::endl;
        
        return api_key;
    }
    
    bool validateAPIKey(const std::string& api_key, APIKeyScope required_scope) {
        auto it = api_keys.find(api_key);
        if (it == api_keys.end() || !it->second.active) {
            return false;
        }
        
        // スコープ確認(ADMIN > READ_WRITE > READ_ONLY)
        int current_level = static_cast<int>(it->second.scope);
        int required_level = static_cast<int>(required_scope);
        
        return current_level >= required_level;
    }
    
    void revokeAPIKey(const std::string& api_key) {
        auto it = api_keys.find(api_key);
        if (it != api_keys.end()) {
            it->second.active = false;
            std::cout << "API key " << api_key << " revoked" << std::endl;
        }
    }
    
    std::vector<std::string> listAPIKeysForUser(const std::string& user_id) {
        std::vector<std::string> user_keys;
        for (const auto& pair : api_keys) {
            if (pair.second.user_id == user_id && pair.second.active) {
                user_keys.push_back(pair.first);
            }
        }
        return user_keys;
    }
};

int main() {
    APIKeyManager api_mgr;
    
    // APIキー生成
    std::string read_key = api_mgr.generateAPIKey("user123", APIKeyScope::READ_ONLY);
    std::string admin_key = api_mgr.generateAPIKey("admin456", APIKeyScope::ADMIN);
    
    // APIキー検証
    if (api_mgr.validateAPIKey(read_key, APIKeyScope::READ_ONLY)) {
        std::cout << "Read access granted" << std::endl;
    }
    
    if (!api_mgr.validateAPIKey(read_key, APIKeyScope::ADMIN)) {
        std::cout << "Admin access denied for read-only key" << std::endl;
    }
    
    return 0;
}

UUIDの文字列変換と比較

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <string>

int main() {
    boost::uuids::random_generator gen;
    
    // UUID生成
    boost::uuids::uuid id1 = gen();
    boost::uuids::uuid id2 = gen();
    
    // 文字列変換(複数の方法)
    std::string str1 = boost::uuids::to_string(id1);
    std::string str2 = boost::lexical_cast<std::string>(id1);
    
    std::cout << "UUID to string: " << str1 << std::endl;
    std::cout << "Lexical cast: " << str2 << std::endl;
    
    // 文字列からUUID
    boost::uuids::string_generator string_gen;
    boost::uuids::uuid id3 = string_gen(str1);
    
    // 比較
    if (id1 == id3) {
        std::cout << "UUIDs match after string conversion" << std::endl;
    }
    
    if (id1 != id2) {
        std::cout << "Different UUIDs are not equal" << std::endl;
    }
    
    // UUID のサイズと生の バイト
    std::cout << "UUID size: " << sizeof(boost::uuids::uuid) << " bytes" << std::endl;
    std::cout << "UUID data: ";
    for (auto byte : id1) {
        std::cout << std::hex << static_cast<int>(byte) << " ";
    }
    std::cout << std::endl;
    
    return 0;
}