Skip to content

ブロックチェーン統合

SirrChat のブロックチェーン統合により、EVM ウォレット署名を使用したパスワードレス認証が可能になります。この革新的なアプローチは、従来のパスワードの脆弱性を排除しながら、暗号的に安全なアクセス制御を提供します。

概要

ブロックチェーン認証モジュール(auth.pass_blockchain)により、ユーザーは従来のパスワードの代わりに Ethereum(または EVM 互換)ウォレット署名を使用して認証できます。

仕組み

  1. ユーザー登録: ユーザーのウォレットアドレスがメールアカウントに登録されます
  2. 認証リクエスト: クライアントが秘密鍵でチャレンジメッセージに署名
  3. 署名検証: サーバーが署名から公開鍵を復元
  4. アクセス許可: 復元されたアドレスが登録アドレスと一致すれば、アクセスが許可されます

設定

基本セットアップ

sirrchatd.conf にブロックチェーン認証を追加:

conf
# ブロックチェーン設定
blockchain sirrchatd {
    rpc_endpoint https://mainnet.infura.io/v3/YOUR_PROJECT_ID
    chain_id 1  # Ethereum Mainnet
}

# 認証モジュール
auth.pass_blockchain blockchain_auth {
    blockchain &sirrchatd
    storage &local_mailboxes
}

# IMAP エンドポイントで使用
imap tls://0.0.0.0:993 {
    auth &blockchain_auth
    storage &local_mailboxes
}

サポートされているチェーン

SirrChat は任意の EVM 互換ブロックチェーンをサポート:

チェーンチェーン IDネットワーク
Ethereum Mainnet1本番環境
Ethereum Goerli5テストネット
Ethereum Sepolia11155111テストネット
BSC Mainnet56本番環境
BSC Testnet97テストネット
Polygon Mainnet137本番環境
Polygon Mumbai80001テストネット
Arbitrum One42161本番環境
Optimism10本番環境

認証フロー

1. チャレンジ生成

ユーザーが認証を試みると、サーバーはチャレンジメッセージを生成:

Challenge: <random_nonce>
Timestamp: <unix_timestamp>
Service: sirrchat

2. クライアント側の署名

クライアントは Ethereum ウォレットを使用してチャレンジに署名:

javascript
// ethers.js を使用した例
const message = `Challenge: ${nonce}\nTimestamp: ${timestamp}\nService: sirrchat`;
const signature = await wallet.signMessage(message);

3. サーバー側の検証

サーバーは署名を検証してアドレスを復元:

go
// 内部検証プロセス
func (bc *Ethereum) CheckSign(ctx context.Context, pk, sign, message string) (bool, error) {
    hash := crypto.Keccak256Hash([]byte(message))
    signature := hexutil.MustDecode(sign)

    // 署名から公開鍵を復元
    pubKey, err := crypto.SigToPub(hash.Bytes(), signature)
    if err != nil {
        return false, err
    }

    // 公開鍵からアドレスを取得
    recoveredAddr := crypto.PubkeyToAddress(*pubKey)

    // 登録アドレスと比較
    return recoveredAddr.Hex() == pk, nil
}

ユーザー管理

ブロックチェーンユーザーを登録

bash
# ウォレットアドレスをメールアカウントに登録
sirrchatd creds create-blockchain \
    --email user@example.com \
    --address 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb

# ブロックチェーンユーザーをリスト
sirrchatd creds list-blockchain

ウォレットアドレスを更新

bash
# 既存のアカウントのウォレットアドレスを更新
sirrchatd creds update-blockchain \
    --email user@example.com \
    --address 0xNewAddress

ブロックチェーン認証を削除

bash
# ブロックチェーン認証を削除(メールアカウントは保持)
sirrchatd creds remove-blockchain --email user@example.com

クライアント実装

メールクライアント設定

ブロックチェーン認証を使用するようにメールクライアントを設定:

IMAP 設定:

  • サーバー: your-domain.com
  • ポート: 993
  • セキュリティ: SSL/TLS
  • ユーザー名: user@example.com
  • パスワード: <signature>(ウォレット署名)

カスタムクライアントの例

カスタムクライアントでブロックチェーン認証を実装する簡単な例:

javascript
const ethers = require('ethers');

class BlockchainEmailAuth {
    constructor(walletAddress, privateKey) {
        this.wallet = new ethers.Wallet(privateKey);
        this.address = walletAddress;
    }

    async generateAuthCredentials(challenge, timestamp) {
        const message = `Challenge: ${challenge}\nTimestamp: ${timestamp}\nService: sirrchat`;
        const signature = await this.wallet.signMessage(message);

        return {
            username: `user@example.com`,
            password: signature,
            address: this.address
        };
    }

    async connectIMAP(host, port) {
        // サーバーからチャレンジを取得
        const { challenge, timestamp } = await this.getChallengeFromServer();

        // 認証情報を生成
        const creds = await this.generateAuthCredentials(challenge, timestamp);

        // IMAP サーバーに接続
        // ... 認証に creds を使用
    }
}

セキュリティに関する考慮事項

ベストプラクティス

  1. 秘密鍵を共有しない: 秘密鍵をサーバーに送信または保存してはいけません
  2. ハードウェアウォレットを使用: 本番環境では、ハードウェアウォレット統合を検討
  3. ノンスの有効期限を実装: チャレンジノンスは短期間で期限切れにする
  4. レート制限: 認証試行にレート制限を実装
  5. 監査ログ: セキュリティ監視のためにすべての認証試行をログに記録

リプレイ攻撃の防止

サーバーにはアンチリプレイ保護が含まれています:

conf
auth.pass_blockchain blockchain_auth {
    blockchain &sirrchatd
    storage &local_mailboxes

    # チャレンジ設定
    challenge_expiry 300s  # 5分
    nonce_cache_size 10000
}

従来の認証との比較の利点

セキュリティ上の利点

  • パスワードストレージなし: パスワードデータベースの侵害を排除
  • 暗号検証: 実証済みの楕円曲線暗号に基づく
  • パスワードの再利用なし: 各署名は一意
  • フィッシング耐性: 認証情報を明かすように騙されることがない

ユーザーエクスペリエンス

  • パスワード管理不要: ユーザーはパスワードを覚える必要がない
  • マルチデバイス: 同じウォレットをすべてのデバイスで使用可能
  • リカバリーオプション: パスワードリセットの代わりにウォレットリカバリーメカニズムを使用

Web3 アプリケーションとの統合

DApp 統合

DApp にメール機能を統合:

javascript
// 例: DApp からメールを送信
async function sendEmailFromDApp(web3Provider) {
    const signer = web3Provider.getSigner();
    const address = await signer.getAddress();

    // チャレンジを取得
    const challenge = await fetchChallenge();

    // チャレンジに署名
    const signature = await signer.signMessage(challenge.message);

    // 認証してメールを送信
    await sendEmail({
        from: `${address}@yourdomain.com`,
        signature: signature,
        to: 'recipient@example.com',
        subject: 'Hello from DApp',
        body: 'This email was sent using blockchain authentication!'
    });
}

トラブルシューティング

一般的な問題

署名検証が失敗

bash
# アドレスが登録されているか確認
sirrchatd creds list-blockchain | grep user@example.com

# チャレンジフォーマットを確認
# クライアントとサーバーが同じメッセージフォーマットを使用していることを確認

RPC 接続の問題

bash
# RPC エンドポイントをテスト
curl -X POST https://mainnet.infura.io/v3/YOUR_PROJECT_ID \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'

高度な設定

複数チェーンのサポート

conf
# 複数のチェーンをサポート
blockchain eth_mainnet {
    rpc_endpoint https://mainnet.infura.io/v3/YOUR_PROJECT_ID
    chain_id 1
}

blockchain bsc_mainnet {
    rpc_endpoint https://bsc-dataseed1.binance.org
    chain_id 56
}

auth.pass_blockchain multi_chain_auth {
    blockchain &eth_mainnet &bsc_mainnet
    storage &local_mailboxes
}

カスタム検証ロジック

カスタム検証のためにブロックチェーンモジュールを拡張:

go
// カスタム検証実装
type CustomBlockchainAuth struct {
    baseAuth *blockchain.Ethereum
}

func (c *CustomBlockchainAuth) VerifyWithNFT(ctx context.Context, address, signature string) (bool, error) {
    // 署名を検証
    valid, err := c.baseAuth.CheckSign(ctx, address, signature, message)
    if err != nil || !valid {
        return false, err
    }

    // 追加の NFT 所有権チェック
    hasNFT, err := c.checkNFTOwnership(ctx, address)
    return hasNFT, err
}

API リファレンス

コアインターフェース

go
type BlockChain interface {
    // ブロックチェーンに生のトランザクションを送信
    SendRawTx(ctx context.Context, rawTx string) error

    // ブロックチェーンタイプを取得
    ChainType(ctx context.Context) string

    // 署名を検証し、公開鍵と一致するかチェック
    CheckSign(ctx context.Context, pk, sign, message string) (bool, error)
}

リソース


ブロックチェーン認証は、暗号検証によるセキュリティを強化しながらパスワードを排除します。

Released under the GPL 3.0 License.