Notice
Recent Posts
Recent Comments
반응형
오늘도 공부
이더리움(Geth)에 사용되는 키스토어 암호화 및 복호화 설명 본문
반응형
geth에서 사용하는 키스토어(Keystore) 암호화 및 복호화 메커니즘은 Ethereum 계정을 안전하게 보호하는 핵심 기능 중 하나입니다. 이 방식은 사용자의 개인 키(private key)를 암호화된 파일로 저장하고, **패스워드(passphrase)**로 이를 잠그는 구조입니다.
🔐 1. 암호화 구조 개요
💾 저장 위치
- 기본 위치: ~/.ethereum/keystore/
- 파일명 형식:
UTC--YYYY-MM-DDThh-mm-ss.nnnnnnnnnZ--0x<address>
📄 저장 내용 (JSON 형식 예시):
{
"address": "2f8a3c...",
"crypto": {
"cipher": "aes-128-ctr",
"ciphertext": "d172a74d2fc3...",
"cipherparams": {
"iv": "83dbcc02d8ccb40e466191a123791e0e"
},
"kdf": "scrypt",
"kdfparams": {
"dklen": 32,
"n": 262144,
"r": 8,
"p": 1,
"salt": "ab0c2a..."
},
"mac": "ab3a1d98..."
},
"id": "uuid",
"version": 3
}
🧪 2. 암호화 방식 상세
🔑 개인 키 암호화 흐름
- 사용자가 패스워드를 입력하면 →
- kdf (Key Derivation Function)으로 암호화 키를 생성
- 기본은 scrypt (n, r, p, salt 설정 사용)
- 또는 pbkdf2를 사용할 수도 있음
- 생성된 키를 사용해 개인키를 AES-128-CTR로 암호화 → ciphertext
- 암호화된 결과와 IV, salt, MAC 등을 포함한 JSON을 생성
MAC 계산
- MAC은 복호화 전에 암호화 데이터의 무결성을 검사하기 위한 용도입니다.
- 계산식:
- MAC = keccak256(derivedKey[16:32] + ciphertext)
🔓 3. 복호화 방식
- 사용자가 암호를 입력하면, 같은 kdf와 파라미터(salt 포함)를 통해 키를 재생성
- MAC 값 검증:
- 재생성된 MAC과 저장된 MAC이 일치하는지 확인
- 일치하면 cipher 방식(aes-128-ctr)으로 복호화하여 개인 키 복원
🛠️ 4. 관련 명령어
계정 생성 시:
geth account new
→ 암호를 입력하면 keystore JSON 파일이 생성됨
계정 복호화 (비공개키 추출):
geth account export 0xYourAddress
또는
geth --exec "eth.accounts" attach
🔥 주의: 복호화된 개인키는 메모리에 로드되므로 반드시 안전한 환경에서 실행하세요.
🧷 5. 기타 보안 팁
- 패스워드는 절대로 키스토어와 같은 곳에 보관하지 마세요.
- 키스토어 파일은 백업할 수 있지만, 패스워드를 잊으면 복호화 불가 (복구 불가능).
- kdf 파라미터 (n, r, p)를 높게 설정하면 보안은 강해지지만, 복호화 속도는 느려짐 → 보안/성능 균형 필요
- Keystore v3 형식은 web3.js, ethers.js, MetaMask 등과 호환됩니다.
파이썬으로 구현하는 키스토어 암호화 및 복호화 예제
다음은 Geth 키스토어 v3 형식에 맞춘 Python 코드로,
- 개인 키를 암호화하여 키스토어 JSON을 생성하는 코드
- 기존 키스토어 JSON을 복호화하여 개인 키를 추출하는 코드입니다.
이 코드는 eth_keyfile 및 eth_keys, web3 모듈을 활용합니다.
📦 1. 설치 필요 패키지
pip install eth-keyfile eth-keys web3
🔐 2. 개인 키 → 키스토어 암호화 (encrypt_key)
from eth_keyfile import create_keyfile_json
from eth_keys import keys
import os, json
# 개인 키: 32바이트 hex string
private_key_hex = "0x4c0883a69102937d6231471b5dbb6204fe512961708279ce96d547bfee8b7f74"
private_key_bytes = bytes.fromhex(private_key_hex[2:])
# 비밀번호
password = "my-secure-password"
# 키스토어 JSON 생성
keyfile_json = create_keyfile_json(
private_key_bytes,
password.encode('utf-8'),
kdf='scrypt' # 또는 'pbkdf2'
)
# 파일 저장 (예: UTC--....json)
address = keys.PrivateKey(private_key_bytes).public_key.to_checksum_address()
file_name = f"UTC--demo--{address}.json"
with open(file_name, 'w') as f:
json.dump(keyfile_json, f)
print(f"🔐 Keystore saved as {file_name}")
🔓 3. 키스토어 → 개인 키 복호화 (decrypt_key)
from eth_keyfile import load_keyfile
import json
# 키스토어 파일 로드
file_path = "UTC--demo--0x....json" # 실제 파일명으로 변경
with open(file_path, 'r') as f:
keyfile_json = json.load(f)
# 비밀번호로 복호화
password = "my-secure-password"
private_key_bytes = load_keyfile(keyfile_json, password.encode('utf-8'))
# 개인 키 출력
private_key_hex = "0x" + private_key_bytes.hex()
print(f"🔓 Decrypted private key: {private_key_hex}")
⚠️ 보안 주의사항
- create_keyfile_json()은 MAC, salt, iv, ciphertext 등을 자동으로 생성합니다.
- 실제 운영환경에서는 절대 private key를 로그에 출력하거나 노출하지 마세요.
- 복호화된 개인키는 메모리에 남으므로 이후 del 등으로 제거하는 것도 고려해야 합니다.
반응형
'블록체인' 카테고리의 다른 글
우분투에서 fish 터미널 셸 설치 및 사용법 (0) | 2025.05.19 |
---|---|
Polygon CDK(블록체인 개발 키트)에 대해 알아보자 (4) | 2025.04.26 |
블록체인에서 <SBT> 는 무엇인가 (1) | 2025.04.10 |