이름은 같은데 값이 다른 것들
SHA3-256과 Keccak-256은 다른 값을 냅니다. 이름만으로는 특정되지 않는 여덟 가지.
문서에 "SHA-3을 쓰라"고 적혀 있어서 SHA3-256으로 계산했는데 상대가 거부합니다.
SHA3-256과 Keccak-256은 다르다
SHA3-256("abc") = 3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532
Keccak-256("abc") = 4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45
완전히 다른 값입니다.
Keccak이 SHA-3 공모전에서 우승한 뒤, NIST가 표준으로 확정하면서 패딩 바이트를 바꿨습니다. 원래 Keccak은 0x01을 붙였고 SHA-3은 0x06을 붙입니다. 그 한 바이트 차이가 전체 출력을 바꿉니다.
이더리움은 표준 확정 전에 원래 Keccak을 채택했고 지금도 그것을 씁니다. 그래서 이더리움 주소나 서명을 SHA3-256으로 계산하면 전부 틀립니다.
라이브러리 이름도 헷갈립니다. 일부 라이브러리의 sha3 함수가 실제로는 Keccak이고, 반대인 경우도 있습니다. 알려진 값("abc")으로 확인하는 것이 확실합니다.
CRC-16은 일곱 가지가 넘는다
이름 다항식 초기값 반전 "123456789" 결과
CRC-16/ARC 0x8005 0x0000 예 0xBB3D
CRC-16/MODBUS 0x8005 0xFFFF 예 0x4B37
CRC-16/CCITT-FALSE 0x1021 0xFFFF 아니오 0x29B1
CRC-16/XMODEM 0x1021 0x0000 아니오 0x31C3
CRC-16/KERMIT 0x1021 0x0000 예 0x2189
같은 다항식 0x1021을 쓰는 셋이 다 다릅니다. 초기값과 반전 여부가 값을 바꿉니다.
"CCITT"라고만 적혀 있으면 CCITT-FALSE와 KERMIT 중 어느 것인지 알 수 없습니다.
base64는 네 가지다
문자셋 62·63번 문자 패딩
표준 + / = 있음
표준 + / = 없음
URL-safe - _ = 있음
URL-safe - _ = 없음
JWT는 URL-safe에 패딩 없음입니다. HTTP 기본 인증은 표준에 패딩 있음입니다. 둘을 섞으면 디코딩이 실패하거나, 더 나쁘게는 조용히 다른 바이트가 나옵니다.
+나 /가 보이면 표준, -나 _가 보이면 URL-safe입니다. 둘 다 없으면 구분할 수 없으므로 문맥으로 정해야 합니다.
시간대 약어
CST 미국 중부 -06:00
CST 중국 +08:00
CST 쿠바 -05:00
IST 인도 +05:30
IST 아일랜드 +01:00
IST 이스라엘 +02:00
약어는 유일하지 않습니다. Asia/Seoul 같은 IANA 지역 이름을 써야 특정됩니다.
단위
1 갤런 미국 3.785L / 영국 4.546L 20% 차이
1 온스 무게 28.35g / 액량(미) 29.57mL 아예 다른 종류
1 톤 미터톤 1000kg / 숏톤 907kg / 롱톤 1016kg
1 kB SI 1000바이트 / 관행 1024바이트
무게 온스와 액량 온스는 하나가 질량이고 하나가 부피라, 이름만 같고 차원이 다릅니다.
MD5는 두 가지 문맥이다
MD5 128비트 해시 함수
md5crypt $1$ 로 시작하는 비밀번호 해시, MD5 를 1000번 돌린다
"MD5로 비밀번호를 저장한다"는 말이 둘 중 어느 쪽인지에 따라 안전성 평가가 달라집니다. 전자는 솔트도 반복도 없고, 후자는 둘 다 있습니다. 둘 다 지금 고를 것은 아니지만 같은 것은 아닙니다.
무엇으로 구분하나
규격이 정한 검사값을 씁니다. CRC 규격은 "123456789"의 값을 함께 적어 둡니다. 해시는 "abc"나 빈 문자열의 값이 널리 공개돼 있습니다. 새 구현을 붙일 때 이것부터 넣어 보면 어느 변종인지 바로 나옵니다.
이름 대신 파라미터를 받습니다. 문서에 "CRC-16"이 아니라 다항식·초기값·반전·최종 XOR이 적혀 있어야 합니다. 시간대는 약어가 아니라 IANA 이름이어야 합니다.
확인 순서
- 해시가 안 맞으면 알려진 검사값(
"abc")으로 어느 변종인지 확인합니다 - 이더리움 관련 코드에서
sha3함수가 실제로 Keccak인지 봅니다 - base64 디코딩이 실패하면 문자셋과 패딩을 봅니다
- 시간대를 약어로 주고받고 있다면 IANA 이름으로 바꿉니다
- 외부 장비·API 문서에서 이름만 적혀 있으면 파라미터를 요청합니다
tools.onuel.dev에서 변종을 나란히 확인할 수 있습니다. SHA3-256과 Keccak-256에 abc를 넣으면 위의 두 값이 그대로 나오고, CRC 계산기는 다항식과 초기값을 직접 지정해 변종을 재현합니다. base64 문자셋 차이는 Base64 인코딩에서, 시간대는 시간대 변환기에서 지역 이름으로 다루고, 단위 계통은 단위 변환기에 함께 있습니다.
- #해시
- #규격
- #호환성