Skip to content

블록체인 통합

SirrMesh의 블록체인 통합은 EVM 지갑 서명을 사용한 비밀번호 없는 인증을 구현합니다. 이 혁신적인 접근 방식은 기존 비밀번호 취약점을 제거하면서 암호학적으로 안전한 액세스 제어를 제공합니다.

개요

블록체인 인증 모듈(auth.pass_blockchain)을 사용하면 사용자가 기존 비밀번호 대신 이더리움(또는 EVM 호환) 지갑 서명을 사용하여 인증할 수 있습니다.

작동 방식

  1. 사용자 등록: 사용자의 지갑 주소가 메일 계정에 등록됩니다
  2. 인증 요청: 클라이언트가 개인 키로 챌린지 메시지에 서명합니다
  3. 서명 검증: 서버가 서명에서 공개 키를 복구합니다
  4. 액세스 부여: 복구된 주소가 등록된 주소와 일치하면 액세스가 부여됩니다

설정

기본 설정

sirrmeshd.conf에 블록체인 인증 추가:

conf
# 블록체인 설정
blockchain bsc {
    rpc_endpoint https://mainnet.infura.io/v3/YOUR_PROJECT_ID
    chain_id 56  # 이더리움 메인넷
}

# 인증 모듈
auth.pass_blockchain blockchain_auth {
    blockchain &evm
    storage &local_mailboxes
}

# IMAP 엔드포인트에서 사용
imap tls://0.0.0.0:993 {
    auth &blockchain_auth
    storage &local_mailboxes
}

지원되는 체인

SirrMesh는 모든 EVM 호환 블록체인을 지원합니다:

체인Chain ID네트워크
이더리움 메인넷1프로덕션
이더리움 Goerli5테스트넷
이더리움 Sepolia11155111테스트넷
BSC 메인넷56프로덕션
BSC 테스트넷97테스트넷
Polygon 메인넷137프로덕션
Polygon Mumbai80001테스트넷
Arbitrum One42161프로덕션
Optimism10프로덕션

인증 흐름

1. 챌린지 생성

사용자가 인증을 시도할 때 서버는 챌린지 메시지를 생성합니다:

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

2. 클라이언트 서명

클라이언트가 이더리움 지갑을 사용하여 챌린지에 서명합니다:

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
# 지갑 주소로 메일 계정 등록
sirrmeshd creds create-blockchain \
    --email [email protected] \
    --address 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb

# 블록체인 사용자 목록 보기
sirrmeshd creds list-blockchain

지갑 주소 업데이트

bash
# 기존 계정의 지갑 주소 업데이트
sirrmeshd creds update-blockchain \
    --email [email protected] \
    --address 0xNewAddress

블록체인 인증 제거

bash
# 블록체인 인증 제거 (메일 계정은 유지)
sirrmeshd 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 서버에 연결
        // ... 자격 증명을 사용하여 인증
    }
}

보안 고려 사항

모범 사례

  1. 개인 키를 공유하지 마세요: 개인 키는 절대로 전송하거나 서버에 저장해서는 안 됩니다
  2. 하드웨어 지갑 사용: 프로덕션 사용 시 하드웨어 지갑 통합 고려
  3. 논스 만료 구현: 챌린지 논스는 짧은 시간 후 만료되어야 합니다
  4. 속도 제한: 인증 시도에 대한 속도 제한 구현
  5. 감사 로깅: 보안 모니터링을 위해 모든 인증 시도 기록

재생 공격 방지

서버는 재생 공격 방지 기능을 포함합니다:

conf
auth.pass_blockchain blockchain_auth {
    blockchain &bsc
    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: 'DApp에서 온 인사',
        body: '이 메일은 블록체인 인증을 사용하여 발송되었습니다!'
    });
}

문제 해결

자주 발생하는 문제

서명 검증 실패

bash
# 주소가 등록되어 있는지 확인
sirrmeshd 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 &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.