ブロックチェーン統合
SirrChat のブロックチェーン統合により、EVM ウォレット署名を使用したパスワードレス認証が可能になります。この革新的なアプローチは、従来のパスワードの脆弱性を排除しながら、暗号的に安全なアクセス制御を提供します。
概要
ブロックチェーン認証モジュール(auth.pass_blockchain)により、ユーザーは従来のパスワードの代わりに Ethereum(または EVM 互換)ウォレット署名を使用して認証できます。
仕組み
- ユーザー登録: ユーザーのウォレットアドレスがメールアカウントに登録されます
- 認証リクエスト: クライアントが秘密鍵でチャレンジメッセージに署名
- 署名検証: サーバーが署名から公開鍵を復元
- アクセス許可: 復元されたアドレスが登録アドレスと一致すれば、アクセスが許可されます
設定
基本セットアップ
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 Mainnet | 1 | 本番環境 |
| Ethereum Goerli | 5 | テストネット |
| Ethereum Sepolia | 11155111 | テストネット |
| BSC Mainnet | 56 | 本番環境 |
| BSC Testnet | 97 | テストネット |
| Polygon Mainnet | 137 | 本番環境 |
| Polygon Mumbai | 80001 | テストネット |
| Arbitrum One | 42161 | 本番環境 |
| Optimism | 10 | 本番環境 |
認証フロー
1. チャレンジ生成
ユーザーが認証を試みると、サーバーはチャレンジメッセージを生成:
Challenge: <random_nonce>
Timestamp: <unix_timestamp>
Service: sirrchat2. クライアント側の署名
クライアントは 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 [email protected] \
--address 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb
# ブロックチェーンユーザーをリスト
sirrchatd creds list-blockchainウォレットアドレスを更新
bash
# 既存のアカウントのウォレットアドレスを更新
sirrchatd creds update-blockchain \
--email [email protected] \
--address 0xNewAddressブロックチェーン認証を削除
bash
# ブロックチェーン認証を削除(メールアカウントは保持)
sirrchatd creds remove-blockchain --email [email protected]クライアント実装
メールクライアント設定
ブロックチェーン認証を使用するようにメールクライアントを設定:
IMAP 設定:
- サーバー: your-domain.com
- ポート: 993
- セキュリティ: SSL/TLS
- ユーザー名: [email protected]
- パスワード:
<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: `[email protected]`,
password: signature,
address: this.address
};
}
async connectIMAP(host, port) {
// サーバーからチャレンジを取得
const { challenge, timestamp } = await this.getChallengeFromServer();
// 認証情報を生成
const creds = await this.generateAuthCredentials(challenge, timestamp);
// IMAP サーバーに接続
// ... 認証に creds を使用
}
}セキュリティに関する考慮事項
ベストプラクティス
- 秘密鍵を共有しない: 秘密鍵をサーバーに送信または保存してはいけません
- ハードウェアウォレットを使用: 本番環境では、ハードウェアウォレット統合を検討
- ノンスの有効期限を実装: チャレンジノンスは短期間で期限切れにする
- レート制限: 認証試行にレート制限を実装
- 監査ログ: セキュリティ監視のためにすべての認証試行をログに記録
リプレイ攻撃の防止
サーバーにはアンチリプレイ保護が含まれています:
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: '[email protected]',
subject: 'Hello from DApp',
body: 'This email was sent using blockchain authentication!'
});
}トラブルシューティング
一般的な問題
署名検証が失敗
bash
# アドレスが登録されているか確認
sirrchatd creds list-blockchain | grep [email protected]
# チャレンジフォーマットを確認
# クライアントとサーバーが同じメッセージフォーマットを使用していることを確認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 ð_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)
}リソース
ブロックチェーン認証は、暗号検証によるセキュリティを強化しながらパスワードを排除します。