일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
Tags
- 스마트 컨트렉트 함수이름 중복
- ethers
- vue기초
- 머신러닝기초
- erc4337 contract
- ethers typescript
- multicall
- git rebase
- 오블완
- erc4337
- 체인의정석
- 계정추상화
- ambiguous function description
- SBT표준
- ethers type
- rust 기초
- Vue.js
- 러스트 기초 학습
- chainlink 설명
- redux toolkit 설명
- 티스토리챌린지
- ethers v6
- 스마트컨트렉트 예약어 함수이름 중복
- ethers websocket
- 컨트렉트 동일한 함수이름 호출
- redux 기초
- 스마트컨트렉트 함수이름 중복 호출
- Vue
- 러스트 기초
- 러스트기초
Archives
- Today
- Total
체인의정석
Cloud HSM에서 ec-point를 통해 유효한 공개키, 지갑주소 뽑아내기 본문
728x90
Cloud HSM에서 공개키에 대한 값을 받을 때 지갑 주소 형태가 아닌 ec-point 라는 값을 받았다.
찾아보니 해당 값에서 공개키를 도출할 때는 상황에 따라 다 다르게 도출을 해야하는것 같다.
일단 설정 값 중 "key-length-bytes": 135 라는 문구가 보였는데
원래 HSM을 쓰기 전 정석적으로 65바이트의 공개키를 사용하고 이후에 그 공개키를 지갑 주소로 변환하는 형태이다.
따라서 135 만큼의 길이가 있다는 것은 특정 부분을 제외하고 공개키를 찾아야 한다는 점이다.
📦 정석적인 EC 공개키 길이
Ethereum에서 사용하는 secp256k1 곡선 기준:
항목 길이 (bytes)
0x04 (접두어) | 1 byte |
X 좌표 | 32 bytes |
Y 좌표 | 32 bytes |
합계 (정상 EC_POINT) | 65 bytes |
그럼 앞부분은 어떤 의미를 가질까?
패딩 또는 길이 필드 포함 | HSM 구현체에 따라 `04 |
ASN.1 또는 DER 헤더 포함 | PKCS#11 또는 CloudHSM은 EC_POINT를 DER 인코딩된 구조로 내보낼 수 있고, 헤더가 앞에 붙거나 중간에 붙음 |
앞뒤로 5~7바이트의 추가 구조 | 135 - 65 = 70 bytes의 초과는 없지만, **135 - 128 = 7 bytes**라면 공개키 외에 앞부분에 불필요한 bytes 7개가 붙어 있을 가능성이 있음 |
✅ 마지막 128바이트가 X + Y 좌표 | 따라서 실제 Ethereum 주소에 필요한 정보는 뒤에서 128 글자 = 64바이트 x좌표 + y좌표만 있다는 해석 가능 |
HSM의 특성에 따라서 구현체에 따른 부분 헤더, 불필요한 bytes등이 들어 잇을 수 있으며 실제 유효한 값은 뒤의 128글자에 해당되는 64byte 라고 한다. 한마디로 "key-length-bytes": 135라는 것은 HSM이 EC 공개키를 내보내면서 앞에 비표준적인 header나 padding을 포함하고 있다는 뜻이며 이에 따라 공개키를 구할 때 마지막 부분을 추출해서 공개키를 만든 후에 지갑 주소로 이후에 만드는 과정이 필요하다.
따라서 해당 방식을 통해 아래와 같은 스크립트를 hardhat에 넣어서 cloud hsm의 지갑주소를 도출할 수 있었다.
import { keccak256 } from 'ethereum-cryptography/keccak';
import { hexToBytes, bytesToHex } from 'ethereum-cryptography/utils';
/**
* CloudHSM EC_POINT에서 Ethereum 주소 도출
*
* 일부 HSM 구현은 EC 공개키(EC_POINT)를 DER 또는 비표준 구조로 내보내며,
* 선행 바이트(header, padding 등)가 포함되어 있을 수 있습니다.
*
* 따라서 가장 신뢰할 수 있는 방식은 EC_POINT의 마지막 128자리 hex 문자열
* (즉, 64바이트: 32바이트 X 좌표 + 32바이트 Y 좌표)만을 추출하여 keccak256 해싱을 수행하고,
* 그 해시의 마지막 20바이트를 Ethereum 주소로 사용하는 것입니다.
*
* @param ecPointHex EC_POINT 값 (hex string, 예: '04abcdef...')
* @returns Ethereum address (0x-prefixed)
*/
export function deriveEthAddressFromEcPoint(ecPointHex: string): string {
const cleanHex = ecPointHex.toLowerCase().replace(/^0x/, '');
if (cleanHex.length < 128) {
throw new Error('EC_POINT 길이가 너무 짧습니다 (최소 128자 필요).');
}
const last128 = cleanHex.slice(-128); // 마지막 64바이트 (X + Y 좌표)
const pubkeyBytes = hexToBytes(last128);
const hash = keccak256(pubkeyBytes);
return '0x' + bytesToHex(hash.slice(-20));
}
// 예시 실행
const ecPoint = 'ECPOINT 값';
console.log('🪪 ETH Address:', deriveEthAddressFromEcPoint(ecPoint));
728x90
반응형
'블록체인 > 퍼블릭 블록체인' 카테고리의 다른 글
Arb Sepolia Testnet 코인 받는법 (Sepolia pow facuet -> bridge) (2) | 2025.05.28 |
---|---|
ERC4337 + Pass Key, 계정추상화에 패스키 적용하기 (0) | 2024.10.14 |
smart contract에서 동일한 함수 이름이나 예약어가 있을 경우 (0) | 2024.09.30 |
smart contract에서 동일한 함수 이름이나 예약어가 있을 경우 (0) | 2024.09.30 |
다중 체인 환경 hardhat써서 로컬에서 테스트하기 (0) | 2024.06.24 |
Comments