이더리움 네트워크에선 서명 시, \x19Ethereum Signed Message:\n 와 평문의 길이를 접두어로 포함 시켜 서명한다. ( 몇몇 네트워크는 접두어가 다를 수 있다.)
개발하면서 항상 서명 중 접두어가 왜 필요한지에 대해 의문이었는데, 몇몇 네트워크는 접두어가 달라서 꽤나 처리하기 귀찮고, 네트워크 추가할 때 마다, 서명 로직 쭉 살펴보면서 접두어 분기 처리 해야하나 확인해야하기 때문이다.
이번에 메세지 서명에 관해 깊게 공부하는 김에 확실히 무슨 용도인지 파악해보고자 한다.
먼저 몇몇 답변들 찾아보면 Replay attack 방지를 위해 존재한다 하는데, 접두어에 Ethereum 있으니 ~ 네트워크 구분용 ~ 이렇게 단순하게 생각하여 나온 답변 같다.
애당초 평문에 수기로 위의 접두어 그대로 복사해서 서명하면 의미가 없을테니 말이다.
좀 더 찾아본 결과, ethers 레포지토리 이슈란에 누군가 질문한 글에 ethers 개발자가 직접 답글을 달았길래 해당 답글을 베이스로 글을 작성하였다.
먼저 결론부터 이야기하자면 다음과 같다.
1. Message prefix는 Replay attack과 관련이 있는가?
-> 전혀 없다.
2. 그럼 무슨 용도인가?
-> %%PREFIX%% 가 붙은 메세지의 해시값을 서명함으로써, 해당 서명이 트랜잭션과 아무런 관련이 없음을 보장한다.
먼저 트랜잭션과 서명이 어떻게 이뤄지는지 간단하게 살펴보자




%%prefix%% 를 붙이면 뭐가 달라지나?
달라진다.
EIP-2718 이전, 레거시 트랜잭션의 경우, RLP 인코딩된 리스트라 볼 수 있다. 즉, RLP 인코딩 특성상, 첫번째 바이트는 [0xC0, 0xFE]( 48 ~ 254)의 범위를 갖게된다.
EIP-2718에서 제시된 새로운 트랜잭션들의 경우, 항상 첫번째 바이트는 트랜잭션 타입을 명시하게 되어있다.
현재 type 2까지 제시되어 있고 간단하게 소개하자면 다음과 같다.
Type 0 - Legacy
RLP([nonce, gasPrice, gasLimit, to, value, data, v, r, s])
Type 1 (EIP-2930) - optional access list
0x01 || rlp([chainId, nonce, gasPrice, gasLimit, to, value, data, accessList, signatureYParity, signatureR, signatureS])
Type 2 (EIP-1559)- Fee market change for ETH 1.0 chain
0x02 || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list, signature_y_parity, signature_r, signature_s])
보다시피, 시작 바이트가 각 타입에 대응하여 1,2로 할당 되어있다.
그리하여 새로운 타입이 추가 될 때마다 타입에 맞는 값을 시작바이트에 삼는데, \x19Ethereum Signed Message:\n 의 경우, 시작 바이트가 25(0x19)이다. 즉, 현재 기준으로 메세지 서명 시, %%PREFIX%%를 접두할 시, 충돌할 가능성이 없다는 의미가 된다.
참고로 만약 타입이 지속적으로 추가되어, 25개째 타입이 추가 된다면, 25를 뛰어 넘고, 26을 할당하는 식으로 처리한다.
Prefix에 대해 전체적인 컨셉을 이해하고 싶다면 아래 토론글을 읽어보면 좋다. ( 사실 읽어도 이해안되는 부분들 있어서 질문해봤는데 정말 빠르게 답장 주셔서.. 글에서 이해안되는게 있다면 질문 올려보는것을 추천한다 )
https://github.com/ethereum/EIPs/pull/683
WIP: eth_signPrefixedData - prefixed data signing by ligi · Pull Request #683 · ethereum/EIPs
As discussed in ethereum/go-ethereum#14794 cc @prusnak, @karalabe
github.com
** Reference **
https://github.com/ethers-io/ethers.js/issues/555
How to sign messages without the "\x19Ethereum Signed Message" prefix? · Issue #555 · ethers-io/ethers.js
We're currently working on a project that needs to interoperate with other platforms and we're using Metamask through a Signer. However, when running something like wallet.signMessage(message) mess...
github.com
https://github.com/ethereum/EIPs/pull/683
WIP: eth_signPrefixedData - prefixed data signing by ligi · Pull Request #683 · ethereum/EIPs
As discussed in ethereum/go-ethereum#14794 cc @prusnak, @karalabe
github.com
'blockchain' 카테고리의 다른 글
[Cosmos + JS] ADR-036 구현하기 (1) | 2023.10.09 |
---|---|
[BIP32] HD지갑(Hierarchical Deterministic Wallet) 훝어보기 (1) | 2023.10.03 |
[Crypto] Signature Replay Attack (0) | 2023.10.02 |
[Ethereum]메세지 서명 (signMessage) (1) | 2023.10.02 |
SECP256k1 훝어보기 (0) | 2023.09.28 |