先までは、"愛記"についての記載で、どのようにブロックチェーンSNSに組み込んで実装していけばよいのか、概念的なところからアプローチ方法を記載していった。概念設計としてはひとまず終えた。次は、フェデレーションモデル全体の基本設計といえるところまで、基本設計書に着手できるようなところまで、概念を具体化していきたい。そして、それにつながるDApps側である「愛記システム」を、Pythonプログラムで開発していきたい。
愛の行動のPL,BSを決算書として、個人単位、市町村単位、で公表するような愛記システムというものを考えている。愛の行動のデータベースはブロックチェーンのプログラムであり、日々の愛の行動による愛貨の移動を決算書にまとめていきたい。なお、市町村のブロックチェーンのプログラムは以前にも記載している。その市町村のブロックチェーンのプログラムにつながる愛記システムを、DApps側であるPythonプログラムとして設計したい。その場合、基本設計をどのような手順で進めていけばよいか、詳しく見ていこう。
愛記システムを設計するための基本手順を以下に示す。このシステムは、Pythonを用いて市町村のブロックチェーンと連携し、個人および市町村単位での愛の行動のデータを収集、記録し、決算書(PL、BS)として公表するものである。
基本設計のステップ
- 要件定義
- アーキテクチャ設計
- データベース設計
- API設計
- ブロックチェーンインターフェース
- 決算書の生成
- フロントエンド開発
- テストとデプロイ
基本設計の各ステップを順番に進めることで、ブロックチェーンとDAppsとして繋がる「愛記システム」の詳細な設計が可能になる。各ステップでは、関係者との協議やレビューを通じて設計内容を確定していくことが重要である。
1.要件定義
まず、基本設計の最初のステップである要件定義をしていきたい。どのような機能が必要か、どのような問題を解決するのかを洗い出したい。要件定義はシステム設計の最初の重要なステップであり、システムが解決するべき問題と、必要な機能を明確に定義するプロセスである。以下に、愛記システムのプログラムに必要な機能と解決すべき問題を列挙してみよう。
機能要件
-
愛の行動の記録
-
愛貨の移動の記録
-
決算書の生成
-
個人および市町村単位でのデータの集約
-
データのブロックチェーンへの記録と取得
-
愛貨の管理
-
ユーザー管理
-
通知機能
-
レポート機能
-
ダッシュボード
非機能要件
-
セキュリティ
-
可用性
-
パフォーマンス
-
スケーラビリティ
-
ユーザビリティ
-
コンプライアンス
解決すべき問題
-
透明性と信頼性の確保
-
データの一元管理
-
愛の行動の促進
-
評価制度の確立
-
データのセキュリティとプライバシーの保護
これらの要件を基に、愛記システムの基本設計を進めていくことが重要である。次のステップでは、これらの要件を具体的なアーキテクチャ設計に反映していくことになる。まずは、要件定義の解決すべき問題を一つずつクリアにしていきたい。
データのセキュリティとプライバシーの保護
次は、データのセキュリティとプライバシーの保護について、今まで記載してきたフェデレーションモデルにおけるブロックチェーンのプログラムとそれに紐付くDApps側であるPythonプログラムにおいて、特にDApps側であるPythonプログラムのデータのセキュリティとプライバシーの保護について、設計していこう。以下は、DApps側であるPythonプログラムのセキュリティとプライバシー保護の設計についての詳細である。
・セキュリティとプライバシー保護のための基本方針
-
データの暗号化:
- データベースに保存する際に、機密情報は暗号化して保存する。
- 通信中のデータもTLS/SSLを使用して暗号化する。
-
認証と認可:
- APIエンドポイントへのアクセスには、トークンベースの認証を導入する。
- 各エンドポイントに適切なアクセス制御を設定する。
-
データの最小化:
- 必要最小限のデータのみを収集・保存し、不要なデータは収集しないようにする。
-
ログと監査:
- システムの操作ログを記録し、定期的に監査する。
-
定期的なセキュリティレビュー:
- コードやインフラストラクチャの定期的なセキュリティレビューを実施する。
- コードやインフラストラクチャの定期的なセキュリティレビューを実施する。
認証と認可:
この設計では、ラティス署名を使用してユーザーの認証情報を署名し、セッション情報を保存する。セッションIDと署名を使用して、エンドポイントへのアクセスを認証・認可する。
1. 必要なモジュールのインポート
from flask import Flask, request, jsonify
from pymongo import MongoClient
import bcrypt
import datetime
from pqcrypto.sign import falcon1024
import base64
app = Flask(__name__)
2. MongoDBの設定
MongoDBに接続し、ユーザーとセッションの情報を保存するためのコレクションを設定する。
client = MongoClient('mongodb://localhost:27017/')
db = client.user_db
users_collection = db.users
sessions_collection = db.sessions
3. ラティス署名用のキーの生成
ラティス署名の鍵ペアを生成し、秘密鍵と公開鍵を使用する。
public_key, private_key = falcon1024.keypair()
4. ユーザー登録エンドポイント
ユーザー登録時に、パスワードをハッシュ化してMongoDBに保存する。
@app.route('/register', methods=['POST'])
def register():
data = request.json
user_id = data.get('user_id')
password = data.get('password')
if not user_id or not password:
return jsonify({'message': 'User ID and password are required!'}), 400
hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
users_collection.insert_one({
'user_id': user_id,
'password': hashed_password,
})
return jsonify({'message': 'User registered successfully!'}), 200
5. 認証情報の署名と検証
ユーザーがログインする際に、認証情報を署名し、セッション情報として保存する。
def sign_data(data):
signature = falcon1024.sign(data.encode(), private_key)
return base64.urlsafe_b64encode(signature).decode().rstrip("=")
def verify_signature(data, signature):
decoded_signature = base64.urlsafe_b64decode(signature + "==")
try:
falcon1024.open(data.encode(), decoded_signature, public_key)
return True
except:
return False
6. ログインエンドポイント
ユーザーのログイン処理を行い、セッション情報を生成してMongoDBに保存する。
@app.route('/login', methods=['POST'])
def login():
data = request.json
user_id = data.get('user_id')
password = data.get('password')
user = users_collection.find_one({'user_id': user_id})
if not user or not bcrypt.checkpw(password.encode('utf-8'), user['password']):
return jsonify({'message': 'Invalid user ID or password'}), 401
session_data = {
'user_id': user_id,
'timestamp': datetime.datetime.utcnow().timestamp()
}
signature = sign_data(str(session_data))
sessions_collection.insert_one({
'user_id': user_id,
'signature': signature,
'timestamp': session_data['timestamp']
})
return jsonify({'session_id': str(session_data), 'signature': signature})
7. セッション検証
セッション情報を検証して、ユーザーを認証する。
def verify_session(session_id, signature):
if verify_signature(session_id, signature):
session_data = eval(session_id)
session = sessions_collection.find_one({'user_id': session_data['user_id'], 'timestamp': session_data['timestamp']})
if session and session['signature'] == signature:
return session_data['user_id']
return None
8. 保護されたエンドポイント
認証済みユーザーのみがアクセスできる保護されたエンドポイントを設定する。
@app.route('/secure-endpoint', methods=['GET'])
def secure_endpoint():
session_id = request.headers.get('Session-ID')
signature = request.headers.get('Signature')
if not session_id or not signature:
return jsonify({'message': 'Session ID or Signature is missing!'}), 403
user_id = verify_session(session_id, signature)
if not user_id:
return jsonify({'message': 'Invalid session or signature!'}), 403
return jsonify({'message': f'Hello, user {user_id}!'})
if __name__ == '__main__':
app.run(debug=True)
・概要
この設計では、ラティス署名を使用してユーザーの認証情報を署名し、セッション情報を保存する。セッションIDと署名を使用して、エンドポイントへのアクセスを認証・認可する。MongoDBを利用してユーザーとセッション情報を管理し、セキュアな認証を実現している。
いかがであろうか、これでDApps側であるPythonプログラムの認証と認可ができた。セキュリティは一つずつ強固に設定していくことが重要であろうから。次回は、データの最小化について見ていきたい。