Arken 推出使用 secp256k1 金鑰的無密碼認證中介軟體
Show HN: Arken – Passwordless auth middleware using secp256k1 keys
Arken 是一套使用 secp256k1 金鑰的無密碼認證中介軟體,讓 Web 伺服器不再儲存密碼或 Session。
- 核心機制:使用者持有私鑰,伺服器只傳送一次性 nonce,客戶端簽名後回傳,伺服器驗證簽名並比對 DID。
此方案消除傳統密碼與 session,提供無縫且抗釣魚的身份驗證,並以 secp256k1 DID 為核心,開源且可直接整合至 Express 或 FastAPI 應用,降低開發與維運成本,同時保持高安全性與跨平臺可攜性。
Arken Auth
無密碼驗證,適用於網路伺服器。無密碼。無會話。無任何可被入侵的專案。
問題
今天的每一個驗證系統都要求伺服器儲存一個秘密——密碼雜湊、會話令牌或 API 金鑰。這個秘密是負擔。它會被入侵、被釣魚,或被按一個沒有人遵守的時間表輪換。
Arken Auth 改變模型:使用者持有秘密,伺服器不持有任何東西。
工作原理
Client Server
│ │
├── GET /protected ────────────────▶│
│ │ (no auth header)
│◀── 401 { challenge: { nonce } } ──┤
│ │
│ sign(nonce, privateKey) │
│ │
├── GET /protected ────────────────▶│
│ Authorization: Signature │
│ did="did:key:z...", │
│ nonce="...", │
│ signature="0x..." │
│ │ recover signer from sig
│ │ compare to DID pubkey
│◀── 200 { did: "did:key:z..." } ───┤
- 客戶端請求受保護的資源——伺服器發放一次性 nonce
- 客戶端用自己的私鑰簽署 nonce(永不離開其裝置)
- 客戶端將簽名 + 他們的 DID 傳回伺服器
- 伺服器從簽名中恢復簽署者地址並檢查其是否與 DID 匹配
- 從未傳輸密碼。未儲存會話。未接觸資料庫。
加密核心用 Rust 寫成,並透過 FFI 從 Node.js 或 Python 呼叫。
快速開始 — Node.js
npm install arken-auth
const express = require('express'); const { arkenAuth } = require('arken-auth'); const app = express(); app.get('/protected', arkenAuth(), (req, res) => { res.json({ message: 'hello', did: req.user.did }); });
就這樣。arkenAuth() 處理整個挑戰-回應週期。
快速開始 — Python
pip install arken-auth
from fastapi import FastAPI, Depends from arken_auth import ArkenAuth app = FastAPI() arken = ArkenAuth() @app.get("/protected") async def protected(did: str = Depends(arken)): return {"message": "hello", "did": did}
客戶端(瀏覽器或 CLI)
任何能簽署 Ethereum 訊息的客戶端皆可使用。在瀏覽器中使用 ethers.js:
// Generate a DID from a wallet const wallet = ethers.Wallet.createRandom(); const did = walletToDid(wallet); // did:key:z... // Step 1: get a challenge const r1 = await fetch('/protected'); const { challenge: { nonce } } = await r1.json(); // 401 // Step 2: sign the nonce const signature = await wallet.signMessage(ethers.utils.toUtf8Bytes(nonce)); // Step 3: authenticate const r2 = await fetch('/protected', { headers: { Authorization: `Signature did="${did}",nonce="${nonce}",signature="${signature}"` } });
何以不同
| 使用者名稱/密碼 | JWT / OAuth | WebAuthn | Arken Auth | |
|---|---|---|---|---|
| 伺服器儲存秘密 | ✗ (hash) | ✗ (secret) | ✓ | ✓ |
| 可無帳號運作 | ✗ | ✗ | ✗ | ✓ |
| 可攜帶身份 | ✗ | ✗ | ✗ | ✓ |
| 不需要 JS SDK | ✓ | ✓ | ✗ | ✓ |
| 語言無關 | ✓ | ✓ | ✓ | ✓ |
| 抗釣魚 | ✗ | ✗ | ✓ | ✓ |
與 WebAuthn 的關鍵差異在於:您的身份(did:key:z...)是 可攜帶 的。它隨您跨伺服器、應用程式與裝置移動。WebAuthn 憑證只繫結於單一來源;DID 只繫結於您的金鑰。
架構
packages/
arken-auth/ Node.js middleware (Express)
arken-auth-py/ Python middleware (FastAPI)
arken-phase1-docker/workspace/
rust-core/ Cryptographic engine (Rust)
src/lib.rs Challenge generation + signature verification
node-wrapper/ Node.js FFI bindings (koffi)
python-wrapper/ Python FFI bindings (ctypes)
public/ Interactive demo UI
Rust 核心透過 FFI 暴露兩個函式:
generate_challenge_into— 產生隨機 nonce,伺服器端儲存並設 60 秒 TTL,回傳 JSONverify_request_into— 解析驗證標頭,驗證 nonce,恢復簽署者,檢查是否符合 DID
DID 格式
Arken 使用 did:key 搭配 secp256k1 金鑰(multicodec 0xe7 0x01),編碼為 multibase base58btc(z 字首):
did:key:z[base58btc(0xe7 0x01 || compressed_pubkey)]
這是 W3C DID Key Method 規範。
需求
- Rust(用於編譯原生函式庫):
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh - Node.js ≥ 18(用於 npm 套件)
- Python ≥ 3.10(用於 pip 套件)
狀態
第一階段 — 運作中的 Express 與 FastAPI 中介軟體。加密核心已完成並測試。
接下來是什麼:
- 預編譯二進位檔(安裝時不需 Rust)
- 會話/令牌層(可選,適用於有狀態應用)
did:web與did:pkh支援- 瀏覽器擴充功能錢包
授權
MIT