암호화된 LS2를 위한 B32

Proposal 149
Closed
Author zzz
Created 2019-03-13
Last Updated 2020-08-05
Target Version 0.9.40
Implemented In 0.9.40

노트

네트워크 배포 및 테스트 진행 중입니다. 사소한 수정이 있을 수 있습니다. 공식 사양은 SPEC를 참조하세요.

개요

표준 Base 32 (“b32”) 주소에는 목적지의 해시가 포함됩니다. 이는 암호화된 ls2(제안 123)에는 작동하지 않습니다.

암호화된 LS2(제안 123)에는 전통적인 base 32 주소를 사용할 수 없습니다. 목적지의 해시만 포함되어 있으며, 비밀 처리되지 않은 공개 키를 제공하지 않습니다. 클라이언트는 리스셋을 가져오고 해독하기 위해 목적지의 공개 키, 서명 유형, 비밀 처리된 서명 유형, 선택적 비밀 또는 개인 키를 알고 있어야 합니다. 따라서 base 32 주소만으로는 충분하지 않습니다. 클라이언트는 전체 목적지(공개 키가 포함됨)나 공개 키 만을 필요로 합니다. 클라이언트에게 주소록에 전체 목적지가 있고, 주소록이 해시에 의한 역순 검색을 지원하면, 공개 키를 검색할 수 있습니다.

따라서 해시 대신 공개 키를 base32 주소에 넣는 새로운 형식이 필요합니다. 이 형식에는 공개 키의 서명 유형과 비밀 처리 스키마의 서명 유형도 포함되어야 합니다.

이 제안서는 이러한 주소에 대한 새로운 b32 형식을 문서화합니다. 논의 중에 이 새로운 형식을 “b33” 주소라고 이름 붙여졌지만, 실제 새로운 형식은 일반적인 “.b32.i2p” 접미사를 유지합니다.

목표

  • 미래의 비밀 처리 스키마를 지원하기 위해 비밀 처리되지 않은 서명 유형과 비밀 처리된 서명 유형을 모두 포함
  • 32바이트보다 큰 공개 키 지원
  • 특히 시작 부분에서 모든 b32 문자가 대부분 무작위여야 함(모든 주소가 동일한 문자로 시작하지 않도록)
  • 해석 가능
  • 비밀 처리 비밀번호 및/또는 클라이언트별 키가 필요하다는 것을 나타냄
  • 오타를 감지하기 위해 체크섬 추가
  • 길이를 최소화하고, 일반적인 사용에서는 DNS 레이블 길이를 63자 미만으로 유지
  • 대소문자 구분 없음이므로 Base 32를 계속 사용
  • 일반적인 “.b32.i2p” 접미사를 유지

비목표

  • 비밀 처리 비밀 및/또는 클라이언트별 키를 포함하는 “비공개” 링크는 지원하지 않음; 이는 보안에 취약합니다.

설계

  • 새로운 형식은 비밀 처리되지 않은 공개 키, 비밀 처리되지 않은 서명 유형, 비밀 처리된 서명 유형을 포함
  • 선택적으로 비밀 및/또는 개인 키를 포함(비공개 링크만 해당)
  • 기존의 “.b32.i2p” 접미사를 사용하되, 더 긴 길이를 가짐
  • 체크섬 추가
  • 암호화된 리스셋에 대한 주소는 56개 이상의 인코딩된 문자(디코딩된 35바이트 이상)로 식별되며, 전통적인 base 32 주소에 비해 52문자(32바이트)와 비교됨

명세

생성 및 인코딩

{56+ chars}.b32.i2p (35+ chars in binary)의 호스트 이름을 다음과 같이 구성합니다:

flag (1 byte)
    비트 0: 1바이트 서명 유형의 경우 0, 2바이트 서명 유형의 경우 1
    비트 1: 비밀이 필요 없는 경우 0, 필요한 경우 1
    비트 2: 클라이언트별 인증이 없는 경우 0,
           클라이언트 개인 키가 필요한 경우 1
    비트 7-3: 사용하지 않음, 0으로 설정

  public key sigtype (1 or 2 bytes as indicated in flags)
    1바이트인 경우 상위 바이트는 0으로 가정

  blinded key sigtype (1 or 2 bytes as indicated in flags)
    1바이트인 경우 상위 바이트는 0으로 가정

  public key
    서명 유형에 의해 암시되는 바이트 수

후처리 및 체크섬:

위와 같이 이진 데이터를 구성합니다.
  체크섬은 little-endian으로 취급합니다.
  checksum = CRC-32(data[3:end])를 계산합니다.
  data[0] ^= (byte) checksum
  data[1] ^= (byte) (checksum >> 8)
  data[2] ^= (byte) (checksum >> 16)

  hostname = Base32.encode(data) || ".b32.i2p"

b32의 끝에 사용되지 않은 비트는 반드시 0이어야 합니다. 표준 56문자(35바이트) 주소의 경우에는 사용되지 않은 비트가 없습니다.

디코딩 및 검증

호스트 이름에서 ".b32.i2p"를 제거합니다.
  data = Base32.decode(hostname)
  checksum = CRC-32(data[3:end])를 계산합니다.
  체크섬은 little-endian으로 취급합니다.
  flags = data[0] ^ (byte) checksum
  1 바이트 서명 유형인 경우:
    pubkey sigtype = data[1] ^ (byte) (checksum >> 8)
    blinded sigtype = data[2] ^ (byte) (checksum >> 16)
  그렇지 않은 경우 (2 바이트 서명 유형):
    pubkey sigtype = data[1] ^ ((byte) (checksum >> 8)) || data[2] ^ ((byte) (checksum >> 16))
    blinded sigtype = data[3] || data[4]
  flag에 따라 나머지를 구문 분석하여 공개 키를 얻음

비밀 및 개인 키 비트

비밀 및 개인 키 비트는 비밀 및/또는 개인 키가 리스셋을 해독하기 위해 필요할 것이라는 것을 클라이언트, 프록시 또는 기타 클라이언트 측 코드에 전달하는 데 사용됩니다. 특정 구현은 사용자가 필요한 데이터를 제공하도록 요구할 수 있으며, 필요한 데이터가 없는 경우 연결 시도를 거부할 수 있습니다.

정당화

  • 해시로 첫 3바이트를 XOR하여 제한된 체크섬 기능을 제공하며, 모든 base32 문자가 시작 부분에서 랜덤화 되도록 보장합니다. 유효한 플래그 및 서명 유형 조합만 몇 가지 존재하므로, 오타가 발생하면 대부분 무효한 조합이 되어 거부됩니다.
  • 일반적인 경우(1바이트 서명 유형, 비밀 없음, 클라이언트별 인증 없음), 호스트 이름은 {56 chars}.b32.i2p가 되며, 35바이트로 해석되어 Tor와 동일합니다.
  • Tor 2바이트 체크섬은 1/64K의 허위 부정률을 가지고 있습니다. 몇 개의 무시되는 바이트를 뺀 3바이트로, 우리의 체크섬은 백만 분의 1에 접근합니다. 대부분의 플래그/서명 유형 조합이 무효하기 때문입니다.
  • Adler-32는 작은 입력에 적합하지 않으며, 작은 변경을 감지하는 데 좋지 않습니다. 대신 CRC-32를 사용합니다. CRC-32는 빠르고 널리 사용됩니다.

캐싱

이 제안서의 범위 외에, 라우터 및/또는 클라이언트는 공개 키와 목적지의 매핑을 기억하고 캐싱(아마도 영구적으로)해야 합니다.

노트

  • 길이로 새로운 형식을 구별합니다. 기존 b32 주소는 항상 {52 chars}.b32.i2p입니다. 새로운 것은 {56+ chars}.b32.i2p입니다.
  • Tor 토론 스레드: https://lists.torproject.org/pipermail/tor-dev/2017-January/011816.html
  • 2바이트 서명 유형은 발생하지 않을 것으로 예상되며, 현재까지는 13입니다. 지금 구현할 필요가 없습니다.
  • 새로운 형식은 점프 링크에서 사용될 수 있으며(점프 서버에서 제공됨), b32와 마찬가지로 사용될 수 있습니다.

문제점

  • 32바이트보다 긴 비밀, 개인 키 또는 공개 키는 DNS 최대 레이블 길이인 63자를 초과할 것입니다. 브라우저는 아마도 신경 쓰지 않을 것입니다.

전환

이전 호환성 문제는 없습니다. 더 긴 b32 주소는 이전 소프트웨어에서 32바이트 해시로 변환되지 못합니다.