Hedera 메시지 서명 검증에 대한 문서에 없는 비밀
Source: Dev.to
문제
Hedera에서 P2P NFT 스왑을 만들고 있었습니다. 모든 것이 정상적으로 동작했지만, 메시지 서명 검증이 계속 실패했습니다.
// Frontend
const signature = await wallet.signMessage("Sign in to MichiMint");
// Backend
const isValid = pubKey.verify(
Buffer.from("Sign in to MichiMint"),
signature
);
// false ❌
같은 메시지, 새로 만든 서명, 올바른 공개키—왜 검증이 false가 되었을까요?
해결책
Hedera 지갑은 서명된 메시지 앞에 숨겨진 프리픽스를 추가합니다.
function prefixMessage(message: string): string {
return '\x19Hedera Signed Message:\n' + message.length + message;
}
프리픽스가 붙은 메시지를 사용해 검증합니다:
// Backend verification
const prefixedMessage = prefixMessage("Sign in to MichiMint");
const isValid = pubKey.verify(Buffer.from(prefixedMessage), signature);
// true ✅
설명
\x19– 트랜잭션 해시 충돌을 방지하는 매직 바이트.Hedera Signed Message:\n– 컨텍스트 식별자.22– 원본 메시지("Sign in to MichiMint")의 길이.- 그 뒤에 원본 메시지가 이어집니다.
Hedera는 서명된 메시지에 대해 Ethereum의 EIP‑191 표준을 채택했으며, 개발자들이 이 프리픽스를 알고 있을 것이라고 가정했습니다. 프리픽스가 없으면 서명이 다른 컨텍스트에서 재사용될 수 있어 보안에 취약해집니다.
영향
이 인사이트는 MichiMint에 적용됩니다 – Hedera에서 예약 트랜잭션을 이용한 최초의 무신뢰 P2P NFT 스왑입니다.