참고
제안 단계가 종료되었습니다. 공식 사양은 SPEC를 참조하세요. 이 제안서는 여전히 배경 정보로 참조될 수 있습니다.
개요
이 제안서는 다양한 형태의 자동화된 식별 및 공격에 대한 NTCP의 저항성을 개선하기 위한 인증된 키 합의 프로토콜을 설명합니다.
제안서는 다음과 같이 구성되어 있습니다: 보안 목표가 먼저 제시되고, 기본 프로토콜에 대한 논의가 이어집니다. 다음으로 모든 프로토콜 메시지의 완전한 명세가 제공됩니다. 마지막으로 router 주소와 버전 식별에 대해 논의됩니다. 일반적인 패딩 스키마에 대한 포괄적 공격을 논의하는 부록과 인증 암호화 알고리즘의 여러 후보들을 포함하는 부록도 함께 포함되어 있습니다.
다른 I2P transport들과 마찬가지로, NTCP2는 I2NP 메시지의 점대점(router-to-router) transport를 위해서만 정의됩니다. 이는 범용 데이터 파이프가 아닙니다.
동기
NTCP 데이터는 첫 번째 메시지 이후에 암호화되며 (첫 번째 메시지는 무작위 데이터로 보임), 따라서 “페이로드 분석"을 통한 프로토콜 식별을 방지합니다. 하지만 여전히 “플로우 분석"을 통한 프로토콜 식별에는 취약합니다. 이는 처음 4개의 메시지 (즉, handshake)가 고정 길이 (288, 304, 448, 48바이트)이기 때문입니다.
각 메시지에 임의의 양의 랜덤 데이터를 추가함으로써, 우리는 이를 훨씬 더 어렵게 만들 수 있습니다.
저자들은 표준 보안 관행에 따르면 TLS와 같은 기존 프로토콜을 사용하는 것이 권장될 것임을 인정하지만, 이것은 Prop104이며 그 자체로 문제점들이 있습니다. 적절한 곳에는 누락된 기능이나 논의 대상을 나타내기 위해 “향후 작업” 단락들이 추가되었습니다.
설계 목표
단일 포트에서 NTCP 1과 2를 지원하고, 자동 감지하며, NetDB에서 단일 “transport” (즉, RouterAddress)로 게시됩니다.
NetDB에서 별도 필드에 버전 1만, 2만, 또는 1+2 지원을 게시하고, 기본값을 버전 1만으로 설정 (버전 지원을 특정 router 버전에 바인딩하지 않음)
모든 구현체(Java/i2pd/Kovri/go)가 각자의 일정에 따라 버전 2 지원을 추가할 수 있도록(또는 추가하지 않을 수 있도록) 보장
핸드셰이크 및 데이터 메시지를 포함한 모든 NTCP 메시지에 무작위 패딩 추가 (즉, 모든 메시지가 16바이트의 배수가 되지 않도록 하는 길이 난독화) 양측이 최소 및 최대 패딩과 패딩 분포를 요청할 수 있는 옵션 메커니즘 제공. 패딩 분포의 세부 사항은 구현에 따라 달라지며 프로토콜 자체에서 지정될 수도 있고 그렇지 않을 수도 있음.
암호화되지 않은 메시지(1과 2)의 내용을 난독화하여 DPI 박스와 AV 시그니처가 쉽게 분류할 수 없도록 충분히 처리합니다. 또한 단일 피어나 피어 집합으로 전송되는 메시지들이 유사한 비트 패턴을 갖지 않도록 보장합니다.
Java 형식으로 인한 DH에서의 비트 손실 수정 Ticket1112, X25519로 전환하여 해결 가능 (아마도?)
실제 키 유도 함수(KDF)로 전환할 것인가, 아니면 DH 결과를 그대로 사용할 것인가?
“probing resistance” (Tor에서 부르는 용어) 추가; 여기에는 replay resistance가 포함됩니다.
2방향 인증 키 교환(2W-AKE)을 유지합니다. 1W-AKE는 우리 애플리케이션에 충분하지 않습니다.
인증의 일부로 (게시된 RouterIdentity 서명 키에서) 가변 타입, 가변 길이 서명을 계속 사용합니다. 인증의 다른 부분으로 RouterInfo에 게시된 정적 공개 키에 의존합니다.
향후 확장성을 위해 handshake에 options/version 추가.
가능한 경우 악의적인 MitM TCP 세그멘테이션에 대한 저항성을 추가합니다.
연결 설정에 필요한 CPU를 크게 증가시키지 말고, 가능하다면 크게 줄여야 함.
메시지 인증(MAC)을 추가하고, 가능하면 HMAC-SHA256과 Poly1305를 사용하며, Adler 체크섬을 제거합니다.
I2NP 헤더 단축 및 간소화: SSU에서와 같이 만료 시간을 4바이트로 단축. 1바이트 절삭된 SHA256 체크섬 제거.
가능하다면, SSU에서와 같이 4메시지, 2라운드 트립 핸드셰이크를 3메시지, 1라운드 트립 핸드셰이크로 줄입니다. 이를 위해서는 메시지 4에 있는 Bob의 서명을 메시지 2로 옮겨야 합니다. 10년 된 이메일/상태/회의 아카이브에서 4메시지를 사용하는 이유를 조사해보세요.
패딩 전 프로토콜 오버헤드를 최소화합니다. 패딩이 추가될 것이고 경우에 따라 많이 추가될 수도 있지만, 패딩 전 오버헤드는 여전히 오버헤드입니다. 저대역폭 노드들이 NTCP2를 사용할 수 있어야 합니다.
재전송 및 시간 편차 탐지를 위한 타임스탬프를 유지합니다.
타임스탬프의 2038년 문제를 방지하고, 최소 2106년까지는 작동해야 함.
최대 메시지 크기를 16K에서 32K 또는 64K로 증가시킵니다.
새로운 암호학적 원시 함수(cryptographic primitives)들은 Java(1.7), C++, Go router 구현에서 사용할 수 있도록 라이브러리에서 쉽게 이용 가능해야 합니다.
설계에 Java, C++, Go 라우터 개발자 대표들을 포함시킨다.
변경 사항을 최소화합니다 (하지만 여전히 많은 변경이 있을 것입니다).
공통 코드 세트에서 두 버전을 모두 지원 (이는 불가능할 수 있으며 어떤 경우든 구현에 의존적임).
Non-Goals
완벽한 DPI 저항성… 이는 플러그형 전송 방식인 Prop109가 될 것입니다.
TLS 기반 (또는 HTTPS와 유사한) 전송… 이는 Prop104입니다.
대칭 스트림 암호화를 변경해도 괜찮습니다.
타이밍 기반 DPI 저항성 (메시지 간 타이밍/지연은 구현에 따라 달라질 수 있으며, 메시지 내 지연은 예를 들어 랜덤 패딩 전송 전을 포함하여 어느 지점에서든 도입될 수 있음). 인위적 지연 (obfs4에서 IAT 또는 inter-arrival time이라고 하는 것)은 프로토콜 자체와는 독립적임.
세션 참여에 대한 부인 가능성 (서명이 포함되어 있음).
부분적으로 재고되거나 논의될 수 있는 비목표:
Deep Packet Inspection (DPI)에 대한 보호 정도
Post-Quantum (PQ) 보안
부인 가능성
Related Goals
- NTCP 1/2 테스트 설정 구현
Security Goals
우리는 세 당사자를 고려합니다:
- Alice, 새로운 세션을 설정하고자 하는 사용자.
- Bob, Alice가 세션을 설정하고자 하는 상대방.
- Mallory, Alice와 Bob 사이의 “중간자(man in the middle)”.
최대 두 명의 참가자가 능동적 공격에 참여할 수 있습니다.
Alice와 Bob 모두 정적 키 쌍을 소유하고 있으며, 이는 그들의 RouterIdentity에 포함되어 있습니다.
제안된 프로토콜은 다음 요구사항 하에서 Alice와 Bob이 공유 비밀 키(K)에 합의할 수 있도록 하려고 시도합니다:
개인키 보안: Bob과 Mallory 모두 Alice의 정적 개인키에 대해 아무것도 알 수 없습니다. 대칭적으로, Alice도 Bob의 정적 개인키에 대해 아무것도 알 수 없습니다.
세션 키 K는 Alice와 Bob만 알고 있다.
완전 순방향 비밀성(Perfect forward secrecy): 합의된 세션 키는 키가 합의된 후 Alice 및/또는 Bob의 정적 개인 키가 노출되더라도 미래에도 비밀로 유지됩니다.
양방향 인증: Alice는 Bob과 세션을 설정했다고 확신하며, 그 반대도 마찬가지입니다.
온라인 DPI에 대한 보호: Alice와 Bob이 간단한 deep packet inspection (DPI) 기술만을 사용하여 프로토콜에 참여하고 있다는 것을 탐지하는 것이 쉽지 않도록 보장합니다. 아래를 참조하십시오.
제한적 부인방지: Alice와 Bob 모두 프로토콜 참여를 부인할 수 없지만, 둘 중 하나가 공유 키를 유출하면 상대방은 전송된 데이터 내용의 진위를 부인할 수 있습니다.
현재 제안은 Station-To-Station (STS) 프로토콜을 기반으로 다섯 가지 요구사항을 모두 제공하려고 시도합니다. 이 프로토콜은 SSU 프로토콜의 기반이기도 합니다.
Additional DPI Discussion
두 가지 DPI 구성 요소를 가정합니다:
1) Online DPI
실시간으로 모든 플로우를 검사하는 온라인 DPI. 연결이 차단되거나 다른 방식으로 조작될 수 있습니다. 연결 데이터나 메타데이터가 식별되어 오프라인 분석을 위해 저장될 수 있습니다. 온라인 DPI는 I2P 네트워크 데이터베이스에 액세스할 수 없습니다. 온라인 DPI는 길이 계산, 필드 검사, XOR과 같은 간단한 계산을 포함하여 제한된 실시간 연산 능력만을 가지고 있습니다. 온라인 DPI는 AES, AEAD, 해싱과 같은 빠른 실시간 암호화 기능을 보유하고 있지만, 이러한 기능을 대부분 또는 모든 플로우에 적용하기에는 비용이 너무 많이 듭니다. 이러한 암호화 작업의 적용은 오프라인 분석을 통해 이전에 식별된 IP/포트 조합의 플로우에만 적용됩니다. 온라인 DPI는 DH나 elligator2와 같은 높은 오버헤드의 암호화 기능을 수행할 능력이 없습니다. 온라인 DPI는 I2P를 탐지하도록 특별히 설계되지 않았지만, 그러한 목적을 위한 제한된 분류 규칙을 가지고 있을 수 있습니다.
온라인 DPI에 의한 프로토콜 식별을 방지하는 것이 목표입니다.
온라인 또는 “직접적인” DPI의 개념은 여기서 다음과 같은 적대자 능력을 포함하는 것으로 간주됩니다:
대상이 송수신하는 모든 데이터를 검사할 수 있는 능력.
블록 암호나 해시 함수 적용과 같이 관찰된 데이터에 대해 작업을 수행할 수 있는 능력.
이전에 전송된 메시지들을 저장하고 비교할 수 있는 기능.
패킷을 수정, 지연 또는 분할하는 능력.
그러나 온라인 DPI는 다음과 같은 제한 사항을 가지고 있다고 가정됩니다:
IP 주소를 router 해시에 매핑할 수 없음. 네트워크 데이터베이스에 실시간으로 액세스할 수 있다면 이는 간단하지만, I2P를 특별히 타겟으로 하는 DPI 시스템이 필요할 것입니다.
프로토콜을 탐지하기 위해 타이밍 정보를 사용할 수 없음.
일반적으로 말해서, 온라인 DPI 도구상자에는 I2P 탐지를 위해 특별히 설계된 내장 도구가 포함되어 있지 않습니다. 여기에는 예를 들어 메시지에 비무작위 패딩을 포함하는 “허니팟” 생성도 포함됩니다. 이것이 다른 요구사항을 충족하는 한 머신러닝 시스템이나 고도로 구성 가능한 DPI 도구를 배제하지는 않는다는 점에 유의하시기 바랍니다.
페이로드 분석에 대응하기 위해 모든 메시지가 랜덤 데이터와 구별할 수 없도록 보장됩니다. 이는 메시지 길이도 랜덤해야 함을 요구하는데, 이는 단순히 랜덤 패딩을 추가하는 것보다 더 복잡합니다. 실제로 부록 A에서 저자들은 순진한(즉, 균등한) 패딩 방식으로는 문제가 해결되지 않는다고 주장합니다. 따라서 부록 A는 랜덤 지연을 포함하거나 제안된 공격에 대해 합리적인 보호를 제공할 수 있는 대안적인 패딩 방식을 개발할 것을 제안합니다.
위 여섯 번째 항목에 대한 보호를 위해, 구현체들은 프로토콜에 무작위 지연을 포함해야 합니다. 이러한 기법들은 본 제안서에서 다루지 않지만, 패딩 길이 문제들도 해결할 수 있습니다. 요약하면, 이 제안서는 페이로드 분석에 대해서는 (부록 A의 고려사항들을 감안했을 때) 양호한 보호를 제공하지만, 플로우 분석에 대해서는 제한적인 보호만을 제공합니다.
2) Offline DPI
오프라인 DPI는 나중에 분석하기 위해 온라인 DPI가 저장한 데이터를 검사합니다. 오프라인 DPI는 I2P를 탐지하도록 특별히 설계될 수 있습니다. 오프라인 DPI는 I2P 네트워크 데이터베이스에 실시간으로 접근할 수 없습니다. 오프라인 DPI는 이 사양서와 다른 I2P 사양서에 접근할 수 있습니다. 오프라인 DPI는 이 사양서에 정의된 모든 암호화 기능을 포함하여 무제한적인 연산 능력을 가지고 있습니다.
오프라인 DPI는 기존 연결을 차단할 능력이 없습니다. 오프라인 DPI는 당사자들의 호스트/포트로 거의 실시간으로 (설정 후 몇 분 이내에) 전송할 수 있는 기능을 가지고 있습니다. 예를 들어 TCP RST입니다. 오프라인 DPI는 “프로빙” 또는 기타 목적으로 이전 메시지를 거의 실시간으로 (설정 후 몇 분 이내에) 재전송 (수정 여부와 관계없이) 할 수 있는 기능을 가지고 있습니다.
오프라인 DPI에 의한 프로토콜 식별을 방지하는 것은 목표가 아닙니다. I2P router들에 의해 구현되는 처음 두 메시지의 모든 난독화된 데이터 디코딩은 오프라인 DPI에 의해서도 구현될 수 있습니다.
이전 메시지의 재전송을 사용한 연결 시도를 거부하는 것이 목표입니다.
Future work
공격자가 패킷을 드롭하거나 재정렬할 때의 프로토콜 동작을 고려하십시오. 이 분야의 최근 흥미로운 연구는 IACR-1150에서 찾을 수 있습니다.
해당 주제와 관련된 기존 문헌을 고려하여 DPI 시스템의 보다 정확한 분류를 제공합니다.
제안된 프로토콜의 공식적인 보안에 대해 논의하며, 이상적으로는 DPI 공격자 모델을 고려한다.
Noise Protocol Framework
이 제안서는 Noise Protocol Framework NOISE (Revision 33, 2017-10-04)를 기반으로 한 요구사항을 제공합니다. Noise는 SSU 프로토콜의 기반이 되는 Station-To-Station 프로토콜과 유사한 속성을 가지고 있습니다. Noise 용어로 말하면, Alice는 개시자(initiator)이고 Bob은 응답자(responder)입니다.
NTCP2는 Noise 프로토콜 Noise_XK_25519_ChaChaPoly_SHA256을 기반으로 합니다. (초기 키 유도 함수에 대한 실제 식별자는 I2P 확장을 나타내기 위해 “Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256"입니다 - 아래 KDF 1 섹션 참조) 이 Noise 프로토콜은 다음 프리미티브를 사용합니다:
Handshake Pattern: XK Alice가 자신의 키를 Bob에게 전송 (X) Alice는 이미 Bob의 정적 키를 알고 있음 (K)
DH Function: X25519 RFC-7748에서 명시된 대로 32바이트 키 길이를 가진 X25519 DH입니다.
Cipher Function: ChaChaPoly RFC-7539 섹션 2.8에 명시된 AEAD_CHACHA20_POLY1305. 12바이트 논스, 처음 4바이트는 0으로 설정.
Hash Function: SHA256 I2P에서 이미 광범위하게 사용되고 있는 표준 32바이트 해시입니다.
보안 목표
이 제안서는 Noise_XK_25519_ChaChaPoly_SHA256에 대한 다음과 같은 개선사항들을 정의합니다. 이러한 개선사항들은 일반적으로 NOISE 섹션 13의 가이드라인을 따릅니다.
평문 임시 키는 알려진 키와 IV를 사용하는 AES 암호화로 난독화됩니다. 이는 elligator2보다 빠릅니다.
무작위 평문 패딩이 메시지 1과 2에 추가됩니다. 평문 패딩은 핸드셰이크 해시(MixHash) 계산에 포함됩니다. 메시지 2와 메시지 3 파트 1에 대한 아래 KDF 섹션을 참조하세요. 무작위 AEAD 패딩이 메시지 3과 데이터 단계 메시지에 추가됩니다.
TCP를 통한 Noise에서 요구되는 것처럼, 그리고 obfs4에서와 같이 2바이트 프레임 길이 필드가 추가됩니다. 이는 데이터 단계 메시지에서만 사용됩니다. 메시지 1과 2 AEAD 프레임은 고정 길이입니다. 메시지 3 파트 1 AEAD 프레임은 고정 길이입니다. 메시지 3 파트 2 AEAD 프레임 길이는 메시지 1에서 지정됩니다.
2바이트 프레임 길이 필드는 obfs4에서와 같이 SipHash-2-4로 난독화됩니다.
페이로드 형식은 메시지 1, 2, 3 및 데이터 단계에 대해 정의됩니다. 물론 이는 Noise에서 정의되지 않습니다.
New Cryptographic Primitives for I2P
기존 I2P router 구현체들은 현재 I2P 프로토콜에서는 필요하지 않지만, 다음과 같은 표준 암호화 기본 요소들에 대한 구현이 필요할 것입니다:
X25519 키 생성 및 DH
AEAD_ChaCha20_Poly1305 (아래에서 ChaChaPoly로 축약)
SipHash-2-4
Processing overhead estimate
3개 메시지의 메시지 크기:
- 64바이트 + 패딩 (NTCP는 288바이트였음) 2) 64바이트 + 패딩 (NTCP는 304바이트였음) 3) 약 64바이트 + Alice router 정보 + 패딩 평균 router 정보는 약 750바이트 패딩 전 총 평균 814바이트 (NTCP는 448바이트였음) 4) NTCP2에서는 필요하지 않음 (NTCP는 48바이트였음)
패딩 전 총계: NTCP2: 942바이트 NTCP: 1088바이트 Alice가 자신의 RouterInfo의 DatabaseStore Message를 보내기 위해 Bob에 연결한 경우, 해당 메시지는 필요하지 않아 약 800바이트를 절약할 수 있습니다.
다음과 같은 암호화 연산들이 각 당사자가 핸드셰이크를 완료하고 데이터 단계를 시작하기 위해 필요합니다:
- AES: 2
- SHA256: 7 (Alice), 6 (Bob) (모든 연결에 대해 미리 계산된 1 Alice, 2 Bob 제외) (HMAC-SHA256 제외)
- HMAC-SHA256: 19
- ChaChaPoly: 4
- X25519 키 생성: 1
- X25519 DH: 3
- 서명 검증: 1 (Bob) (Alice는 이전에 RI 생성 시 서명함) Ed25519로 추정됨 (RI 서명 유형에 따라 다름)
각 당사자가 각 데이터 단계 메시지에 대해 수행해야 하는 암호화 연산은 다음과 같습니다:
- SipHash: 1
- ChaChaPoly: 1
Messages
모든 NTCP2 메시지는 길이가 65537바이트 이하입니다. 메시지 형식은 Noise 메시지를 기반으로 하며, 프레이밍과 구별 불가성을 위한 수정사항이 있습니다. 표준 Noise 라이브러리를 사용하는 구현체는 수신된 메시지를 Noise 메시지 형식으로/에서 전처리해야 할 수 있습니다. 모든 암호화된 필드는 AEAD 암호문입니다.
설정 순서는 다음과 같습니다:
Alice Bob
SessionRequest ------------------->
<------------------- SessionCreated
SessionConfirmed ----------------->
Noise 용어를 사용하여, 설정 및 데이터 시퀀스는 다음과 같습니다: (페이로드 보안 속성)
XK(s, rs): Authentication Confidentiality
<- s
...
-> e, es 0 2
<- e, ee 2 1
-> s, se 2 5
<- 2 5
세션이 설정되면 Alice와 Bob은 데이터 메시지를 교환할 수 있습니다.
모든 메시지 유형(SessionRequest, SessionCreated, SessionConfirmed, Data 및 TimeSync)이 이 섹션에서 명시됩니다.
일부 표기법:
- RH_A = Alice의 Router Hash (32바이트)
- RH_B = Bob의 Router Hash (32바이트)
Authenticated Encryption
세 개의 별도 인증 암호화 인스턴스(CipherState)가 있습니다. 하나는 핸드셰이크 단계에서, 그리고 두 개(송신 및 수신)는 데이터 단계에서 사용됩니다. 각각은 KDF에서 나온 고유한 키를 가지고 있습니다.
암호화/인증된 데이터는 다음과 같이 표현됩니다
+----+----+----+----+----+----+----+----+
| |
+ +
| Encrypted and authenticated data |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
목표가 아닌 것들
암호화되고 인증된 데이터 형식.
암호화/복호화 함수에 대한 입력:
k :: 32 byte cipher key, as generated from KDF
nonce :: Counter-based nonce, 12 bytes.
Starts at 0 and incremented for each message.
First four bytes are always zero.
Last eight bytes are the counter, little-endian encoded.
Maximum value is 2**64 - 2.
Connection must be dropped and restarted after
it reaches that value.
The value 2**64 - 1 must never be sent.
ad :: In handshake phase:
Associated data, 32 bytes.
The SHA256 hash of all preceding data.
In data phase:
Zero bytes
data :: Plaintext data, 0 or more bytes
암호화 함수의 출력, 복호화 함수의 입력:
+----+----+----+----+----+----+----+----+
|Obfs Len | |
+----+----+ +
| ChaCha20 encrypted data |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
| Poly1305 Message Authentication Code |
+ (MAC) +
| 16 bytes |
+----+----+----+----+----+----+----+----+
Obfs Len :: Length of (encrypted data + MAC) to follow, 16 - 65535
Obfuscation using SipHash (see below)
Not used in message 1 or 2, or message 3 part 1, where the length is fixed
Not used in message 3 part 1, as the length is specified in message 1
encrypted data :: Same size as plaintext data, 0 - 65519 bytes
MAC :: Poly1305 message authentication code, 16 bytes
ChaCha20의 경우, 여기에서 설명하는 내용은 TLS RFC-7905에서도 유사하게 사용되는 RFC-7539에 해당합니다.
Notes
ChaCha20은 스트림 암호이므로, 평문을 패딩할 필요가 없습니다. 추가 키스트림 바이트는 폐기됩니다.
암호의 키(256비트)는 SHA256 KDF를 통해 합의됩니다. 각 메시지에 대한 KDF의 세부 사항은 아래 별도 섹션에 있습니다.
메시지 1, 2, 그리고 메시지 3의 첫 번째 부분에 대한 ChaChaPoly 프레임은 알려진 크기입니다. 메시지 3의 두 번째 부분부터 시작하여, 프레임은 가변 크기입니다. 메시지 3 파트 1 크기는 메시지 1에서 지정됩니다. 데이터 단계부터 시작하여, 프레임은 obfs4에서와 같이 SipHash로 난독화된 2바이트 길이가 앞에 붙습니다.
패딩은 메시지 1과 2에서 인증된 데이터 프레임 외부에 위치합니다. 패딩은 다음 메시지를 위한 KDF에서 사용되므로 변조가 감지됩니다. 메시지 3부터는 패딩이 인증된 데이터 프레임 내부에 위치합니다.
관련 목표
메시지 1, 2, 그리고 메시지 3의 파트 1과 2에서는 AEAD 메시지 크기가 미리 알려져 있습니다. AEAD 인증 실패 시, 수신자는 추가 메시지 처리를 중단하고 응답 없이 연결을 닫아야 합니다. 이는 비정상 종료(TCP RST)여야 합니다.
프로빙 저항을 위해, 메시지 1에서 AEAD 실패 후, Bob은 랜덤 타임아웃(범위 TBD)을 설정하고 소켓을 닫기 전에 랜덤한 수의 바이트(범위 TBD)를 읽어야 한다. Bob은 반복적인 실패가 발생한 IP들의 블랙리스트를 유지해야 한다.
데이터 단계에서 AEAD 메시지 크기는 SipHash로 “암호화”(난독화)됩니다. 복호화 오라클 생성을 피하도록 주의해야 합니다. 데이터 단계 AEAD 인증 실패 시, 수신자는 임의의 타임아웃(범위 TBD)을 설정한 후 임의의 바이트 수(범위 TBD)를 읽어야 합니다. 읽기 완료 후 또는 읽기 타임아웃 시, 수신자는 “AEAD 실패” 이유 코드를 포함하는 종료 블록이 있는 페이로드를 전송하고 연결을 닫아야 합니다.
데이터 단계에서 유효하지 않은 길이 필드 값에 대해 동일한 오류 조치를 취합니다.
Key Derivation Function (KDF) (for handshake message 1)
KDF는 DH 결과로부터 핸드셰이크 단계 암호 키 k를 생성하며, RFC-2104에 정의된 HMAC-SHA256(key, data)를 사용합니다. 이것들은 InitializeSymmetric(), MixHash(), 그리고 MixKey() 함수들로, Noise 사양에 정의된 것과 정확히 동일합니다.
This is the "e" message pattern:
// Define protocol_name.
Set protocol_name = "Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256"
(48 bytes, US-ASCII encoded, no NULL termination).
// Define Hash h = 32 bytes
h = SHA256(protocol_name);
Define ck = 32 byte chaining key. Copy the h data to ck.
Set ck = h
Define rs = Bob's 32-byte static key as published in the RouterInfo
// MixHash(null prologue)
h = SHA256(h);
// up until here, can all be precalculated by Alice for all outgoing connections
// Alice must validate that Bob's static key is a valid point on the curve here.
// Bob static key
// MixHash(rs)
// || below means append
h = SHA256(h || rs);
// up until here, can all be precalculated by Bob for all incoming connections
This is the "e" message pattern:
Alice generates her ephemeral DH key pair e.
// Alice ephemeral key X
// MixHash(e.pubkey)
// || below means append
h = SHA256(h || e.pubkey);
// h is used as the associated data for the AEAD in message 1
// Retain the Hash h for the message 2 KDF
End of "e" message pattern.
This is the "es" message pattern:
// DH(e, rs) == DH(s, re)
Define input_key_material = 32 byte DH result of Alice's ephemeral key and Bob's static key
Set input_key_material = X25519 DH result
// MixKey(DH())
Define temp_key = 32 bytes
Define HMAC-SHA256(key, data) as in [RFC-2104](https://tools.ietf.org/html/rfc2104)
// Generate a temp key from the chaining key and DH result
// ck is the chaining key, defined above
temp_key = HMAC-SHA256(ck, input_key_material)
// overwrite the DH result in memory, no longer needed
input_key_material = (all zeros)
// Output 1
// Set a new chaining key from the temp key
// byte() below means a single byte
ck = HMAC-SHA256(temp_key, byte(0x01)).
// Output 2
// Generate the cipher key k
Define k = 32 bytes
// || below means append
// byte() below means a single byte
k = HMAC-SHA256(temp_key, ck || byte(0x02)).
// overwrite the temp_key in memory, no longer needed
temp_key = (all zeros)
// retain the chaining key ck for message 2 KDF
End of "es" message pattern.
추가 DPI 논의
Alice가 Bob에게 전송합니다.
Noise 내용: Alice의 ephemeral key X Noise 페이로드: 16바이트 옵션 블록 Non-noise 페이로드: 랜덤 패딩
(페이로드 보안 속성)
XK(s, rs): Authentication Confidentiality
-> e, es 0 2
Authentication: None (0).
This payload may have been sent by any party, including an active attacker.
Confidentiality: 2.
Encryption to a known recipient, forward secrecy for sender compromise
only, vulnerable to replay. This payload is encrypted based only on DHs
involving the recipient's static key pair. If the recipient's static
private key is compromised, even at a later date, this payload can be
decrypted. This message can also be replayed, since there's no ephemeral
contribution from the recipient.
"e": Alice generates a new ephemeral key pair and stores it in the e
variable, writes the ephemeral public key as cleartext into the
message buffer, and hashes the public key along with the old h to
derive a new h.
"es": A DH is performed between the Alice's ephemeral key pair and the
Bob's static key pair. The result is hashed along with the old ck to
derive a new ck and k, and n is set to zero.
X 값은 페이로드 구별불가성과 고유성을 보장하기 위해 암호화되며, 이는 필요한 DPI 대응책입니다. 이를 달성하기 위해 elligator2와 같은 더 복잡하고 느린 대안보다는 AES 암호화를 사용합니다. Bob의 router 공개 키에 대한 비대칭 암호화는 너무 느릴 것입니다. AES 암호화는 Bob의 router 해시를 키로 사용하고 네트워크 데이터베이스에 게시된 Bob의 IV를 사용합니다.
AES 암호화는 DPI 저항을 위해서만 사용됩니다. 네트워크 데이터베이스에 공개된 Bob의 router 해시와 IV를 알고 있는 어떤 당사자든 이 메시지의 X 값을 복호화할 수 있습니다.
패딩은 Alice에 의해 암호화되지 않습니다. 타이밍 공격을 억제하기 위해 Bob이 패딩을 복호화하는 것이 필요할 수 있습니다.
원본 내용:
+----+----+----+----+----+----+----+----+
| |
+ obfuscated with RH_B +
| AES-CBC-256 encrypted X |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| |
+ +
| ChaChaPoly frame |
+ (32 bytes) +
| k defined in KDF for message 1 |
+ n = 0 +
| see KDF for associated data |
+----+----+----+----+----+----+----+----+
| unencrypted authenticated |
~ padding (optional) ~
| length defined in options block |
+----+----+----+----+----+----+----+----+
X :: 32 bytes, AES-256-CBC encrypted X25519 ephemeral key, little endian
key: RH_B
iv: As published in Bobs network database entry
padding :: Random data, 0 or more bytes.
Total message length must be 65535 bytes or less.
Total message length must be 287 bytes or less if
Bob is publishing his address as NTCP
(see Version Detection section below).
Alice and Bob will use the padding data in the KDF for message 2.
It is authenticated so that any tampering will cause the
next message to fail.
암호화되지 않은 데이터 (Poly1305 인증 태그는 표시되지 않음):
+----+----+----+----+----+----+----+----+
| |
+ +
| X |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| options |
+ (16 bytes) +
| |
+----+----+----+----+----+----+----+----+
| unencrypted authenticated |
+ padding (optional) +
| length defined in options block |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
X :: 32 bytes, X25519 ephemeral key, little endian
options :: options block, 16 bytes, see below
padding :: Random data, 0 or more bytes.
Total message length must be 65535 bytes or less.
Total message length must be 287 bytes or less if
Bob is publishing his address as "NTCP"
(see Version Detection section below)
Alice and Bob will use the padding data in the KDF for message 2.
It is authenticated so that any tampering will cause the
next message to fail.
옵션 블록: 참고: 모든 필드는 빅 엔디안입니다.
+----+----+----+----+----+----+----+----+
| id | ver| padLen | m3p2len | Rsvd(0) |
+----+----+----+----+----+----+----+----+
| tsA | Reserved (0) |
+----+----+----+----+----+----+----+----+
id :: 1 byte, the network ID (currently 2, except for test networks)
As of 0.9.42. See proposal 147.
ver :: 1 byte, protocol version (currently 2)
padLen :: 2 bytes, length of the padding, 0 or more
Min/max guidelines TBD. Random size from 0 to 31 bytes minimum?
(Distribution to be determined, see Appendix A.)
m3p2Len :: 2 bytes, length of the the second AEAD frame in SessionConfirmed
(message 3 part 2) See notes below
Rsvd :: 2 bytes, set to 0 for compatibility with future options
tsA :: 4 bytes, Unix timestamp, unsigned seconds.
Wraps around in 2106
Reserved :: 4 bytes, set to 0 for compatibility with future options
Notes
게시된 주소가 “NTCP"일 때, Bob은 같은 포트에서 NTCP와 NTCP2를 모두 지원합니다. 호환성을 위해 “NTCP"로 게시된 주소에 연결을 시작할 때, Alice는 패딩을 포함한 이 메시지의 최대 크기를 287바이트 이하로 제한해야 합니다. 이는 Bob의 자동 프로토콜 식별을 용이하게 합니다. “NTCP2"로 게시된 경우에는 크기 제한이 없습니다. 아래의 게시된 주소 및 버전 감지 섹션을 참조하십시오.
초기 AES 블록의 고유한 X 값은 모든 세션에 대해 암호문이 다르게 되도록 보장합니다.
Bob은 타임스탬프 값이 현재 시간과 너무 많이 차이나는 연결을 거부해야 합니다. 최대 델타 시간을 “D"라고 합니다. Bob은 이전에 사용된 핸드셰이크 값들의 로컬 캐시를 유지하고 중복을 거부하여 재생 공격(replay attack)을 방지해야 합니다. 캐시의 값들은 최소 2*D의 수명을 가져야 합니다. 캐시 값들은 구현에 따라 다르지만, 32바이트 X 값(또는 그 암호화된 동등값)을 사용할 수 있습니다.
Diffie-Hellman 임시 키는 암호학적 공격을 방지하기 위해 절대 재사용되어서는 안 되며, 재사용 시 재생 공격으로 간주되어 거부됩니다.
“KE"와 “auth” 옵션은 호환되어야 합니다. 즉, 공유 비밀 K는 적절한 크기여야 합니다. 더 많은 “auth” 옵션이 추가되면, 이는 “KE” 플래그의 의미를 암묵적으로 변경하여 다른 KDF나 다른 잘림 크기를 사용하게 할 수 있습니다.
Bob은 여기서 Alice의 임시 키가 곡선상의 유효한 점인지 검증해야 합니다.
패딩은 합리적인 양으로 제한되어야 합니다. Bob은 과도한 패딩이 있는 연결을 거부할 수 있습니다. Bob은 메시지 2에서 자신의 패딩 옵션을 지정할 것입니다. 최소/최대 가이드라인은 TBD입니다. 최소 0에서 31바이트의 랜덤 크기? (분포는 결정될 예정, 부록 A 참조.)
AEAD, DH, timestamp, 명백한 replay, 또는 키 검증 실패를 포함한 모든 오류 발생 시, Bob은 추가적인 메시지 처리를 중단하고 응답 없이 연결을 종료해야 합니다. 이는 비정상적인 종료(TCP RST)여야 합니다. probing 저항을 위해 AEAD 실패 후, Bob은 랜덤 타임아웃(범위 TBD)을 설정한 다음 랜덤한 바이트 수(범위 TBD)를 읽고 소켓을 종료해야 합니다.
DoS 완화: DH는 상대적으로 비용이 많이 드는 연산입니다. 이전 NTCP 프로토콜과 마찬가지로, router들은 CPU 또는 연결 고갈을 방지하기 위해 필요한 모든 조치를 취해야 합니다. 최대 활성 연결 수와 진행 중인 최대 연결 설정 수에 제한을 둡니다. 읽기 타임아웃을 적용합니다 (읽기당 타임아웃과 “slowloris"에 대한 전체 타임아웃 모두). 동일한 소스로부터의 반복적이거나 동시 연결을 제한합니다. 반복적으로 실패하는 소스에 대한 블랙리스트를 유지합니다. AEAD 실패에 응답하지 않습니다.
빠른 버전 감지 및 handshaking을 위해, 구현체들은 Alice가 패딩을 포함한 첫 번째 메시지의 전체 내용을 버퍼링한 후 한 번에 플러시하도록 해야 합니다. 이는 데이터가 단일 TCP 패킷에 포함될 가능성을 높이고(OS나 middlebox에 의해 분할되지 않는 한), Bob이 한 번에 모든 데이터를 수신할 수 있도록 합니다. 또한 구현체들은 Bob이 패딩을 포함한 두 번째 메시지의 전체 내용을 버퍼링한 후 한 번에 플러시하도록 해야 하며, Bob이 세 번째 메시지의 전체 내용도 버퍼링한 후 한 번에 플러시하도록 해야 합니다. 이는 효율성과 랜덤 패딩의 효과를 보장하기 위함입니다.
“ver” 필드: 전체 Noise 프로토콜, 확장 기능, 그리고 페이로드 사양을 포함한 NTCP 프로토콜로서 NTCP2를 나타냅니다. 이 필드는 향후 변경 사항에 대한 지원을 나타내는 데 사용될 수 있습니다.
Message 3 part 2 길이: 이는 SessionConfirmed 메시지에서 전송될 Alice의 Router Info와 선택적 패딩을 포함하는 두 번째 AEAD 프레임의 크기입니다(16바이트 MAC 포함). router들이 주기적으로 Router Info를 재생성하고 재배포하므로, message 3이 전송되기 전에 현재 Router Info의 크기가 변경될 수 있습니다. 구현체는 두 가지 전략 중 하나를 선택해야 합니다: a) message 3에서 전송할 현재 Router Info를 저장하여 크기를 알 수 있도록 하고, 선택적으로 패딩을 위한 공간을 추가합니다; b) Router Info 크기의 가능한 증가를 허용할 수 있을 만큼 지정된 크기를 늘리고, message 3이 실제로 전송될 때 항상 패딩을 추가합니다. 어느 경우든, message 1에 포함된 “m3p2len” 길이는 message 3에서 전송될 때 해당 프레임의 정확한 크기여야 합니다.
Bob은 메시지 1을 검증하고 패딩을 읽어들인 후 남아있는 수신 데이터가 있으면 연결을 실패 처리해야 합니다. Bob이 아직 메시지 2로 응답하지 않았으므로 Alice로부터 추가 데이터가 있어서는 안 됩니다.
network ID 필드는 교차 네트워크 연결을 빠르게 식별하는 데 사용됩니다. 이 필드가 0이 아니고 Bob의 network ID와 일치하지 않으면, Bob은 연결을 끊고 향후 연결을 차단해야 합니다. 0.9.42부터 적용. 자세한 정보는 proposal 147을 참조하십시오.
Key Derivation Function (KDF) (for handshake message 2 and message 3 part 1)
// take h saved from message 1 KDF
// MixHash(ciphertext)
h = SHA256(h || 32 byte encrypted payload from message 1)
// MixHash(padding)
// Only if padding length is nonzero
h = SHA256(h || random padding from message 1)
This is the "e" message pattern:
Bob generates his ephemeral DH key pair e.
// h is from KDF for handshake message 1
// Bob ephemeral key Y
// MixHash(e.pubkey)
// || below means append
h = SHA256(h || e.pubkey);
// h is used as the associated data for the AEAD in message 2
// Retain the Hash h for the message 3 KDF
End of "e" message pattern.
This is the "ee" message pattern:
// DH(e, re)
Define input_key_material = 32 byte DH result of Alice's ephemeral key and Bob's ephemeral key
Set input_key_material = X25519 DH result
// overwrite Alice's ephemeral key in memory, no longer needed
// Alice:
e(public and private) = (all zeros)
// Bob:
re = (all zeros)
// MixKey(DH())
Define temp_key = 32 bytes
Define HMAC-SHA256(key, data) as in [RFC-2104](https://tools.ietf.org/html/rfc2104)
// Generate a temp key from the chaining key and DH result
// ck is the chaining key, from the KDF for handshake message 1
temp_key = HMAC-SHA256(ck, input_key_material)
// overwrite the DH result in memory, no longer needed
input_key_material = (all zeros)
// Output 1
// Set a new chaining key from the temp key
// byte() below means a single byte
ck = HMAC-SHA256(temp_key, byte(0x01)).
// Output 2
// Generate the cipher key k
Define k = 32 bytes
// || below means append
// byte() below means a single byte
k = HMAC-SHA256(temp_key, ck || byte(0x02)).
// overwrite the temp_key in memory, no longer needed
temp_key = (all zeros)
// retain the chaining key ck for message 3 KDF
End of "ee" message pattern.
2) SessionCreated
Bob이 Alice에게 보냅니다.
Noise 내용: Bob의 ephemeral key Y Noise 페이로드: 16바이트 옵션 블록 Non-noise 페이로드: 랜덤 패딩
(페이로드 보안 속성)
XK(s, rs): Authentication Confidentiality
<- e, ee 2 1
Authentication: 2.
Sender authentication resistant to key-compromise impersonation (KCI).
The sender authentication is based on an ephemeral-static DH ("es" or "se")
between the sender's static key pair and the recipient's ephemeral key pair.
Assuming the corresponding private keys are secure, this authentication cannot be forged.
Confidentiality: 1.
Encryption to an ephemeral recipient.
This payload has forward secrecy, since encryption involves an ephemeral-ephemeral DH ("ee").
However, the sender has not authenticated the recipient,
so this payload might be sent to any party, including an active attacker.
"e": Bob generates a new ephemeral key pair and stores it in the e variable,
writes the ephemeral public key as cleartext into the message buffer,
and hashes the public key along with the old h to derive a new h.
"ee": A DH is performed between the Bob's ephemeral key pair and the Alice's ephemeral key pair.
The result is hashed along with the old ck to derive a new ck and k, and n is set to zero.
Y 값은 페이로드의 구별 불가능성과 고유성을 보장하기 위해 암호화되며, 이는 필수적인 DPI 대응책입니다. 이를 위해 elligator2와 같은 더 복잡하고 느린 대안보다는 AES 암호화를 사용합니다. Alice의 router 공개 키에 대한 비대칭 암호화는 너무 느릴 것입니다. AES 암호화는 Bob의 router 해시를 키로 사용하고 메시지 1의 AES 상태를 사용합니다(이는 netDb에 게시된 Bob의 IV로 초기화되었습니다).
AES 암호화는 DPI 저항을 위해서만 사용됩니다. Bob의 router 해시와 IV를 알고 있는 당사자는 (이들은 네트워크 데이터베이스에 공개됨) 메시지 1의 처음 32바이트를 캡처했다면 이 메시지의 Y 값을 복호화할 수 있습니다.
원시 내용:
+----+----+----+----+----+----+----+----+
| |
+ obfuscated with RH_B +
| AES-CBC-256 encrypted Y |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| ChaChaPoly frame |
+ Encrypted and authenticated data +
| 32 bytes |
+ k defined in KDF for message 2 +
| n = 0; see KDF for associated data |
+ +
| |
+----+----+----+----+----+----+----+----+
| unencrypted authenticated |
+ padding (optional) +
| length defined in options block |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
Y :: 32 bytes, AES-256-CBC encrypted X25519 ephemeral key, little endian
key: RH_B
iv: Using AES state from message 1
암호화되지 않은 데이터 (Poly1305 인증 태그는 표시되지 않음):
+----+----+----+----+----+----+----+----+
| |
+ +
| Y |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| options |
+ (16 bytes) +
| |
+----+----+----+----+----+----+----+----+
| unencrypted authenticated |
+ padding (optional) +
| length defined in options block |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
Y :: 32 bytes, X25519 ephemeral key, little endian
options :: options block, 16 bytes, see below
padding :: Random data, 0 or more bytes.
Total message length must be 65535 bytes or less.
Alice and Bob will use the padding data in the KDF for message 3 part 1.
It is authenticated so that any tampering will cause the
next message to fail.
Notes
Alice는 여기서 Bob의 임시 키가 곡선 상의 유효한 점인지 검증해야 합니다.
패딩은 합리적인 양으로 제한되어야 합니다. Alice는 과도한 패딩이 있는 연결을 거부할 수 있습니다. Alice는 메시지 3에서 자신의 패딩 옵션을 명시할 것입니다. 최소/최대 가이드라인은 미정입니다. 최소 0에서 31바이트까지의 랜덤 크기? (분포는 결정될 예정이며, 부록 A를 참조하세요.)
오류 발생 시 (AEAD, DH, timestamp, 명백한 replay, 또는 키 검증 실패 포함), Alice는 추가 메시지 처리를 중단하고 응답 없이 연결을 종료해야 합니다. 이는 비정상적인 종료(TCP RST)여야 합니다.
신속한 핸드셰이킹을 촉진하기 위해, 구현체들은 Bob이 패딩을 포함한 첫 번째 메시지의 전체 내용을 버퍼링한 다음 한 번에 플러시하도록 보장해야 합니다. 이는 데이터가 (OS나 미들박스에 의해 분할되지 않는 한) 단일 TCP 패킷에 포함되어 Alice가 한 번에 수신할 가능성을 높입니다. 이는 또한 효율성과 무작위 패딩의 효과를 보장하기 위함입니다.
Alice는 메시지 2를 검증하고 패딩을 읽어들인 후 남아있는 수신 데이터가 있으면 연결을 실패시켜야 한다. Alice가 아직 메시지 3으로 응답하지 않았으므로 Bob으로부터 추가 데이터가 있어서는 안 된다.
옵션 블록: 참고: 모든 필드는 big-endian입니다.
+----+----+----+----+----+----+----+----+
| Rsvd(0) | padLen | Reserved (0) |
+----+----+----+----+----+----+----+----+
| tsB | Reserved (0) |
+----+----+----+----+----+----+----+----+
Reserved :: 10 bytes total, set to 0 for compatibility with future options
padLen :: 2 bytes, big endian, length of the padding, 0 or more
Min/max guidelines TBD. Random size from 0 to 31 bytes minimum?
(Distribution to be determined, see Appendix A.)
tsB :: 4 bytes, big endian, Unix timestamp, unsigned seconds.
Wraps around in 2106
Notes
- Alice는 타임스탬프 값이 현재 시간과 너무 많이 차이나는 연결을 거부해야 합니다. 최대 델타 시간을 “D"라고 합니다. Alice는 이전에 사용된 handshake 값들의 로컬 캐시를 유지하고 중복을 거부하여 재생 공격을 방지해야 합니다. 캐시의 값들은 최소 2*D의 수명을 가져야 합니다. 캐시 값들은 구현에 따라 다르지만, 32바이트 Y 값(또는 그 암호화된 동등물)을 사용할 수 있습니다.
Issues
- 여기에 최소/최대 패딩 옵션을 포함할까요?
Encryption for for handshake message 3 part 1, using message 2 KDF)
// take h saved from message 2 KDF
// MixHash(ciphertext)
h = SHA256(h || 24 byte encrypted payload from message 2)
// MixHash(padding)
// Only if padding length is nonzero
h = SHA256(h || random padding from message 2)
// h is used as the associated data for the AEAD in message 3 part 1, below
This is the "s" message pattern:
Define s = Alice's static public key, 32 bytes
// EncryptAndHash(s.publickey)
// EncryptWithAd(h, s.publickey)
// AEAD_ChaCha20_Poly1305(key, nonce, associatedData, data)
// k is from handshake message 1
// n is 1
ciphertext = AEAD_ChaCha20_Poly1305(k, n++, h, s.publickey)
// MixHash(ciphertext)
// || below means append
h = SHA256(h || ciphertext);
// h is used as the associated data for the AEAD in message 3 part 2
End of "s" message pattern.
Key Derivation Function (KDF) (for handshake message 3 part 2)
This is the "se" message pattern:
// DH(s, re) == DH(e, rs)
Define input_key_material = 32 byte DH result of Alice's static key and Bob's ephemeral key
Set input_key_material = X25519 DH result
// overwrite Bob's ephemeral key in memory, no longer needed
// Alice:
re = (all zeros)
// Bob:
e(public and private) = (all zeros)
// MixKey(DH())
Define temp_key = 32 bytes
Define HMAC-SHA256(key, data) as in [RFC-2104](https://tools.ietf.org/html/rfc2104)
// Generate a temp key from the chaining key and DH result
// ck is the chaining key, from the KDF for handshake message 1
temp_key = HMAC-SHA256(ck, input_key_material)
// overwrite the DH result in memory, no longer needed
input_key_material = (all zeros)
// Output 1
// Set a new chaining key from the temp key
// byte() below means a single byte
ck = HMAC-SHA256(temp_key, byte(0x01)).
// Output 2
// Generate the cipher key k
Define k = 32 bytes
// || below means append
// byte() below means a single byte
k = HMAC-SHA256(temp_key, ck || byte(0x02)).
// h from message 3 part 1 is used as the associated data for the AEAD in message 3 part 2
// EncryptAndHash(payload)
// EncryptWithAd(h, payload)
// AEAD_ChaCha20_Poly1305(key, nonce, associatedData, data)
// n is 0
ciphertext = AEAD_ChaCha20_Poly1305(k, n++, h, payload)
// MixHash(ciphertext)
// || below means append
h = SHA256(h || ciphertext);
// retain the chaining key ck for the data phase KDF
// retain the hash h for the data phase Additional Symmetric Key (SipHash) KDF
End of "se" message pattern.
// overwrite the temp_key in memory, no longer needed
temp_key = (all zeros)
3) SessionConfirmed
Alice가 Bob에게 전송합니다.
Noise 내용: Alice의 정적 키 Noise 페이로드: Alice의 RouterInfo 및 랜덤 패딩 Non-noise 페이로드: 없음
(페이로드 보안 속성)
XK(s, rs): Authentication Confidentiality
-> s, se 2 5
Authentication: 2.
Sender authentication resistant to key-compromise impersonation (KCI). The
sender authentication is based on an ephemeral-static DH ("es" or "se")
between the sender's static key pair and the recipient's ephemeral key
pair. Assuming the corresponding private keys are secure, this
authentication cannot be forged.
Confidentiality: 5.
Encryption to a known recipient, strong forward secrecy. This payload is
encrypted based on an ephemeral-ephemeral DH as well as an ephemeral-static
DH with the recipient's static key pair. Assuming the ephemeral private
keys are secure, and the recipient is not being actively impersonated by an
attacker that has stolen its static private key, this payload cannot be
decrypted.
"s": Alice writes her static public key from the s variable into the
message buffer, encrypting it, and hashes the output along with the old h
to derive a new h.
"se": A DH is performed between the Alice's static key pair and the Bob's
ephemeral key pair. The result is hashed along with the old ck to derive a
new ck and k, and n is set to zero.
이것은 두 개의 ChaChaPoly 프레임을 포함합니다. 첫 번째는 Alice의 암호화된 정적 공개 키입니다. 두 번째는 Noise payload입니다: Alice의 암호화된 RouterInfo, 선택적 옵션들, 그리고 선택적 패딩입니다. 이들은 서로 다른 키를 사용하는데, 그 사이에 MixKey() 함수가 호출되기 때문입니다.
원본 내용:
+----+----+----+----+----+----+----+----+
| |
+ ChaChaPoly frame (48 bytes) +
| Encrypted and authenticated |
+ Alice static key S +
| (32 bytes) |
+ +
| k defined in KDF for message 2 |
+ n = 1 +
| see KDF for associated data |
+ +
| |
+----+----+----+----+----+----+----+----+
| |
+ Length specified in message 1 +
| |
+ ChaChaPoly frame +
| Encrypted and authenticated |
+ +
| Alice RouterInfo |
+ using block format 2 +
| Alice Options (optional) |
+ using block format 1 +
| Arbitrary padding |
+ using block format 254 +
| |
+ +
| k defined in KDF for message 3 part 2 |
+ n = 0 +
| see KDF for associated data |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
S :: 32 bytes, ChaChaPoly encrypted Alice's X25519 static key, little endian
inside 48 byte ChaChaPoly frame
암호화되지 않은 데이터 (Poly1305 인증 태그는 표시되지 않음):
+----+----+----+----+----+----+----+----+
| |
+ +
| S |
+ Alice static key +
| (32 bytes) |
+ +
| |
+ +
+----+----+----+----+----+----+----+----+
| |
+ +
| |
+ +
| Alice RouterInfo block |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
| |
+ Optional Options block +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
| |
+ Optional Padding block +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
S :: 32 bytes, Alice's X25519 static key, little endian
1) 온라인 DPI
Bob은 일반적인 Router Info 검증을 수행해야 합니다. 서명 유형이 지원되는지 확인하고, 서명을 검증하며, 타임스탬프가 범위 내에 있는지 확인하고, 기타 필요한 검사를 수행합니다.
Bob은 첫 번째 프레임에서 받은 Alice의 정적 키가 Router Info의 정적 키와 일치하는지 확인해야 합니다. Bob은 먼저 Router Info에서 일치하는 버전(v) 옵션을 가진 NTCP 또는 NTCP2 Router Address를 찾아야 합니다. 아래의 Published Router Info 및 Unpublished Router Info 섹션을 참조하세요.
Bob이 자신의 netdb에서 Alice의 RouterInfo의 구버전을 가지고 있다면, 두 버전 모두에 static key가 존재하는 경우 router info의 static key가 동일한지 확인하고, 구버전이 XXX보다 오래되지 않았는지 확인한다 (아래 key rotate time 참조)
Bob은 여기서 Alice의 정적 키가 곡선상의 유효한 점인지 검증해야 합니다.
패딩 매개변수를 지정하기 위해 옵션이 포함되어야 합니다.
어떤 오류(AEAD, RI, DH, 타임스탬프, 또는 키 검증 실패 포함)가 발생해도 Bob은 추가 메시지 처리를 중단하고 응답 없이 연결을 닫아야 합니다. 이는 비정상 종료(TCP RST)여야 합니다.
빠른 핸드셰이킹을 촉진하기 위해, 구현체들은 Alice가 두 AEAD 프레임을 모두 포함하여 세 번째 메시지의 전체 내용을 버퍼링한 다음 한 번에 플러시하도록 보장해야 합니다. 이는 데이터가 단일 TCP 패킷에 포함될 가능성을 높이고(OS나 미들박스에 의해 분할되지 않는 한), Bob이 모든 데이터를 한 번에 수신할 수 있게 합니다. 이는 또한 효율성을 위해서이며 랜덤 패딩의 효과를 보장하기 위함입니다.
Message 3 part 2 프레임 길이: 이 프레임의 길이(MAC 포함)는 Alice가 message 1에서 전송합니다. 패딩을 위한 충분한 공간 확보에 대한 중요한 참고사항은 해당 메시지를 참조하세요.
Message 3 part 2 프레임 내용: 이 프레임의 형식은 데이터 단계 프레임의 형식과 동일하지만, 프레임의 길이는 message 1에서 Alice가 보낸 것입니다. 데이터 단계 프레임 형식은 아래를 참조하세요. 이 프레임은 다음 순서로 1개에서 3개의 블록을 포함해야 합니다:
- Alice의 Router Info 블록 (필수)
- Options 블록 (선택사항)
- Padding 블록 (선택사항) 이 프레임은 다른 블록 유형을 포함해서는 안 됩니다.
메시지 3 파트 2 패딩은 Alice가 메시지 3 끝에 데이터 단계 프레임을 (패딩을 선택적으로 포함하여) 추가하고 둘을 한 번에 전송하는 경우 필요하지 않습니다. 관찰자에게는 하나의 큰 바이트 스트림으로 나타날 것이기 때문입니다. Alice는 일반적으로 (항상은 아니지만) Bob에게 보낼 I2NP 메시지를 가지고 있을 것이므로 (그래서 그에게 연결한 것입니다), 효율성을 위해 그리고 랜덤 패딩의 효과를 보장하기 위해 이것이 권장되는 구현입니다.
두 Message 3 AEAD 프레임(파트 1과 2)의 총 길이는 65535바이트입니다; 파트 1은 48바이트이므로 파트 2의 최대 프레임 길이는 65487입니다; 파트 2의 MAC를 제외한 최대 평문 길이는 65471입니다.
Key Derivation Function (KDF) (for data phase)
데이터 단계에서는 길이가 0인 연관 데이터 입력을 사용합니다.
KDF는 chaining key ck로부터 두 개의 암호화 키 k_ab와 k_ba를 생성하며, RFC-2104에서 정의된 HMAC-SHA256(key, data)를 사용합니다. 이는 Noise 사양에서 정확히 정의된 Split() 함수입니다.
ck = from handshake phase
// k_ab, k_ba = HKDF(ck, zerolen)
// ask_master = HKDF(ck, zerolen, info="ask")
// zerolen is a zero-length byte array
temp_key = HMAC-SHA256(ck, zerolen)
// overwrite the chaining key in memory, no longer needed
ck = (all zeros)
// Output 1
// cipher key, for Alice transmits to Bob (Noise doesn't make clear which is which, but Java code does)
k_ab = HMAC-SHA256(temp_key, byte(0x01)).
// Output 2
// cipher key, for Bob transmits to Alice (Noise doesn't make clear which is which, but Java code does)
k_ba = HMAC-SHA256(temp_key, k_ab || byte(0x02)).
KDF for SipHash for length field:
Generate an Additional Symmetric Key (ask) for SipHash
SipHash uses two 8-byte keys (big endian) and 8 byte IV for first data.
// "ask" is 3 bytes, US-ASCII, no null termination
ask_master = HMAC-SHA256(temp_key, "ask" || byte(0x01))
// sip_master = HKDF(ask_master, h || "siphash")
// "siphash" is 7 bytes, US-ASCII, no null termination
// overwrite previous temp_key in memory
// h is from KDF for message 3 part 2
temp_key = HMAC-SHA256(ask_master, h || "siphash")
// overwrite ask_master in memory, no longer needed
ask_master = (all zeros)
sip_master = HMAC-SHA256(temp_key, byte(0x01))
Alice to Bob SipHash k1, k2, IV:
// sipkeys_ab, sipkeys_ba = HKDF(sip_master, zerolen)
// overwrite previous temp_key in memory
temp_key = HMAC-SHA256(sip_master, zerolen)
// overwrite sip_master in memory, no longer needed
sip_master = (all zeros)
sipkeys_ab = HMAC-SHA256(temp_key, byte(0x01)).
sipk1_ab = sipkeys_ab[0:7], little endian
sipk2_ab = sipkeys_ab[8:15], little endian
sipiv_ab = sipkeys_ab[16:23]
Bob to Alice SipHash k1, k2, IV:
sipkeys_ba = HMAC-SHA256(temp_key, sipkeys_ab || byte(0x02)).
sipk1_ba = sipkeys_ba[0:7], little endian
sipk2_ba = sipkeys_ba[8:15], little endian
sipiv_ba = sipkeys_ba[16:23]
// overwrite the temp_key in memory, no longer needed
temp_key = (all zeros)
4) Data Phase
Noise payload: 아래에 정의된 대로, 무작위 패딩 포함 Non-noise payload: 없음
메시지 3의 두 번째 부분부터 시작하여, 모든 메시지는 2바이트 난독화된 길이가 앞에 붙는 인증되고 암호화된 ChaChaPoly “프레임” 내부에 있습니다. 모든 패딩은 프레임 내부에 있습니다. 프레임 내부에는 0개 이상의 “블록"이 있는 표준 형식이 있습니다. 각 블록은 1바이트 타입과 2바이트 길이를 가집니다. 타입에는 날짜/시간, I2NP 메시지, 옵션, 종료, 패딩이 포함됩니다.
참고: Bob은 데이터 단계에서 Alice에게 보내는 첫 번째 메시지로 자신의 RouterInfo를 Alice에게 보낼 수 있지만, 반드시 보내야 하는 것은 아닙니다.
(페이로드 보안 속성)
XK(s, rs): Authentication Confidentiality
<- 2 5
-> 2 5
Authentication: 2.
Sender authentication resistant to key-compromise impersonation (KCI).
The sender authentication is based on an ephemeral-static DH ("es" or "se")
between the sender's static key pair and the recipient's ephemeral key pair.
Assuming the corresponding private keys are secure, this authentication cannot be forged.
Confidentiality: 5.
Encryption to a known recipient, strong forward secrecy.
This payload is encrypted based on an ephemeral-ephemeral DH as well as
an ephemeral-static DH with the recipient's static key pair.
Assuming the ephemeral private keys are secure, and the recipient is not being actively impersonated
by an attacker that has stolen its static private key, this payload cannot be decrypted.
2) 오프라인 DPI
효율성을 위해서 그리고 길이 필드의 식별을 최소화하기 위해서, 구현체는 송신자가 길이 필드와 AEAD 프레임을 포함하여 데이터 메시지의 전체 내용을 한 번에 버퍼링한 다음 플러시하도록 보장해야 합니다. 이는 데이터가 (OS나 중간 장치에 의해 분할되지 않는 한) 단일 TCP 패킷에 포함되고 상대방이 한 번에 모두 수신할 가능성을 높입니다. 이는 또한 효율성을 위해서이며 랜덤 패딩의 효과를 보장하기 위해서입니다.
라우터는 AEAD 오류 시 세션을 종료하도록 선택할 수 있으며, 또는 통신을 계속 시도할 수 있습니다. 계속하는 경우, 라우터는 반복적인 오류 후에 종료해야 합니다.
SipHash obfuscated length
참조: SipHash
양측이 핸드셰이크를 완료하면, ChaChaPoly “프레임"에서 암호화되고 인증된 페이로드를 전송합니다.
각 프레임은 2바이트 길이, big endian이 앞에 붙습니다. 이 길이는 MAC를 포함하여 뒤따르는 암호화된 프레임 바이트 수를 지정합니다. 스트림에서 식별 가능한 길이 필드 전송을 방지하기 위해, 프레임 길이는 데이터 단계 KDF에서 초기화된 SipHash에서 파생된 마스크와 XOR하여 난독화됩니다. 두 방향은 KDF에서 고유한 SipHash 키와 IV를 가진다는 점에 유의하십시오.
sipk1, sipk2 = The SipHash keys from the KDF. (two 8-byte long integers)
IV[0] = sipiv = The SipHash IV from the KDF. (8 bytes)
length is big endian.
For each frame:
IV[n] = SipHash-2-4(sipk1, sipk2, IV[n-1])
Mask[n] = First 2 bytes of IV[n]
obfuscatedLength = length ^ Mask[n]
The first length output will be XORed with with IV[1].
수신자는 동일한 SipHash 키와 IV를 가지고 있습니다. 길이 디코딩은 길이를 난독화하는 데 사용된 마스크를 유도하고 잘린 다이제스트를 XOR하여 프레임의 길이를 얻는 방식으로 수행됩니다. 프레임 길이는 MAC을 포함한 암호화된 프레임의 전체 길이입니다.
향후 작업
- 부호 없는 long 정수를 반환하는 SipHash 라이브러리 함수를 사용하는 경우, 최하위 2바이트를 Mask로 사용하세요. long 정수를 little endian으로 다음 IV로 변환하세요.
인증된 암호화
+----+----+----+----+----+----+----+----+
|obf size | |
+----+----+ +
| |
+ ChaChaPoly frame +
| Encrypted and authenticated |
+ key is k_ab for Alice to Bob +
| key is k_ba for Bob to Alice |
+ as defined in KDF for data phase +
| n starts at 0 and increments |
+ for each frame in that direction +
| no associated data |
+ 16 bytes minimum +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
obf size :: 2 bytes length obfuscated with SipHash
when de-obfuscated: 16 - 65535
Minimum size including length field is 18 bytes.
Maximum size including length field is 65537 bytes.
Obfuscated length is 2 bytes.
Maximum ChaChaPoly frame is 65535 bytes.
ChaCha20/Poly1305
암호화된 프레임에는 0개 이상의 블록이 있습니다. 각 블록은 1바이트 식별자, 2바이트 길이, 그리고 0개 이상의 데이터 바이트를 포함합니다.
확장성을 위해 수신자는 알 수 없는 식별자를 가진 블록을 무시하고 패딩으로 처리해야 합니다.
암호화된 데이터는 16바이트 인증 헤더를 포함하여 최대 65535바이트이므로, 암호화되지 않은 데이터의 최대 크기는 65519바이트입니다.
(Poly1305 인증 태그는 표시되지 않음):
+----+----+----+----+----+----+----+----+
|blk | size | data |
+----+----+----+ +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
|blk | size | data |
+----+----+----+ +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
~ . . . ~
blk :: 1 byte
0 for datetime
1 for options
2 for RouterInfo
3 for I2NP message
4 for termination
224-253 reserved for experimental features
254 for padding
255 reserved for future extension
size :: 2 bytes, big endian, size of data to follow, 0 - 65516
data :: the data
Maximum ChaChaPoly frame is 65535 bytes.
Poly1305 tag is 16 bytes
Maximum total block size is 65519 bytes
Maximum single block size is 65519 bytes
Block type is 1 byte
Block length is 2 bytes
Maximum single block data size is 65516 bytes.
Block Ordering Rules
핸드셰이크 메시지 3의 파트 2에서는 순서가 다음과 같아야 합니다: RouterInfo, 그 다음 Options(있는 경우), 그 다음 Padding(있는 경우). 다른 블록은 허용되지 않습니다.
데이터 단계에서 순서는 명시되지 않지만, 다음 요구 사항은 예외입니다: Padding이 있는 경우 마지막 블록이어야 하며, Termination이 있는 경우 Padding을 제외하고 마지막 블록이어야 합니다.
단일 프레임에 여러 개의 I2NP 블록이 있을 수 있습니다. 단일 프레임에서는 여러 개의 Padding 블록이 허용되지 않습니다. 다른 블록 유형들은 아마 단일 프레임에 여러 블록을 갖지 않을 것이지만, 금지되지는 않습니다.
AEAD 오류 처리
시간 동기화의 특수한 경우:
+----+----+----+----+----+----+----+
| 0 | 4 | timestamp |
+----+----+----+----+----+----+----+
blk :: 0
size :: 2 bytes, big endian, value = 4
timestamp :: Unix timestamp, unsigned seconds.
Wraps around in 2106
Key Derivation Function (KDF) (핸드셰이크 메시지 1용)
업데이트된 옵션을 전달합니다. 옵션에는 최소 및 최대 패딩이 포함됩니다.
Options 블록은 가변 길이입니다.
+----+----+----+----+----+----+----+----+
| 1 | size |tmin|tmax|rmin|rmax|tdmy|
+----+----+----+----+----+----+----+----+
|tdmy| rdmy | tdelay | rdelay | |
~----+----+----+----+----+----+----+ ~
| more_options |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
blk :: 1
size :: 2 bytes, big endian, size of options to follow, 12 bytes minimum
tmin, tmax, rmin, rmax :: requested padding limits
tmin and rmin are for desired resistance to traffic analysis.
tmax and rmax are for bandwidth limits.
tmin and tmax are the transmit limits for the router sending this options block.
rmin and rmax are the receive limits for the router sending this options block.
Each is a 4.4 fixed-point float representing 0 to 15.9375
(or think of it as an unsigned 8-bit integer divided by 16.0).
This is the ratio of padding to data. Examples:
Value of 0x00 means no padding
Value of 0x01 means add 6 percent padding
Value of 0x10 means add 100 percent padding
Value of 0x80 means add 800 percent (8x) padding
Alice and Bob will negotiate the minimum and maximum in each direction.
These are guidelines, there is no enforcement.
Sender should honor receiver's maximum.
Sender may or may not honor receiver's minimum, within bandwidth constraints.
tdmy: Max dummy traffic willing to send, 2 bytes big endian, bytes/sec average
rdmy: Requested dummy traffic, 2 bytes big endian, bytes/sec average
tdelay: Max intra-message delay willing to insert, 2 bytes big endian, msec average
rdelay: Requested intra-message delay, 2 bytes big endian, msec average
Padding distribution specified as additional parameters?
Random delay specified as additional parameters?
more_options :: Format TBD
1) SessionRequest
- 옵션 형식은 TBD입니다.
- 옵션 협상은 TBD입니다.
RouterInfo
Alice의 RouterInfo를 Bob에게 전달합니다. 핸드셰이크 메시지 3 파트 2에서 사용됩니다. Alice의 RouterInfo를 Bob에게 전달하거나, Bob의 것을 Alice에게 전달합니다. 데이터 단계에서 선택적으로 사용됩니다.
+----+----+----+----+----+----+----+----+
| 2 | size |flg | RouterInfo |
+----+----+----+----+ +
| (Alice RI in handshake msg 3 part 2) |
~ (Alice, Bob, or third-party ~
| RI in data phase) |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
blk :: 2
size :: 2 bytes, big endian, size of flag + router info to follow
flg :: 1 byte flags
bit order: 76543210
bit 0: 0 for local store, 1 for flood request
bits 7-1: Unused, set to 0 for future compatibility
routerinfo :: Alice's or Bob's RouterInfo
Notes
데이터 단계에서 사용될 때, 수신자(Alice 또는 Bob)는 원래 전송된(Alice의 경우) 또는 전송 대상(Bob의 경우)과 동일한 Router Hash인지 검증해야 합니다. 그런 다음 로컬 I2NP DatabaseStore Message로 처리합니다. 서명을 검증하고, 더 최신 타임스탬프를 검증한 후, 로컬 netDb에 저장합니다. 플래그 비트 0이 1이고 수신 측이 floodfill인 경우, 0이 아닌 응답 토큰이 있는 DatabaseStore Message로 처리하고 가장 가까운 floodfill들에게 플러딩합니다.
Router Info는 gzip으로 압축되지 않습니다 (DatabaseStore Message에서는 압축되는 것과 달리)
RouterInfo에 게시된 RouterAddress가 있지 않는 한 플러딩을 요청해서는 안 됩니다. 수신 router는 RouterInfo에 게시된 RouterAddress가 없는 한 RouterInfo를 플러드해서는 안 됩니다.
구현자들은 블록을 읽을 때, 잘못된 형식이나 악의적인 데이터가 다음 블록으로의 읽기 오버런을 발생시키지 않도록 보장해야 합니다.
이 프로토콜은 RouterInfo가 수신, 저장 또는 전파되었다는 확인응답을 제공하지 않습니다 (핸드셰이크 단계나 데이터 단계 모두에서). 확인응답이 필요하고 수신자가 floodfill인 경우, 발신자는 대신 응답 토큰이 포함된 표준 I2NP DatabaseStoreMessage를 보내야 합니다.
Issues
데이터 단계에서 I2NP DatabaseStoreMessage 대신 사용할 수도 있습니다. 예를 들어, Bob이 데이터 단계를 시작하는 데 사용할 수 있습니다.
이것이 originator가 아닌 다른 router들의 RI를 포함하는 것이 허용되는가? 예를 들어 floodfill들에 의한 flooding을 위해 DatabaseStoreMessages의 일반적인 대체재로서 사용되는 것이?
Key Derivation Function (KDF) (handshake 메시지 2와 메시지 3 파트 1용)
수정된 헤더가 있는 단일 I2NP 메시지입니다. I2NP 메시지는 블록 간이나 ChaChaPoly 프레임 간에 분할될 수 없습니다.
이것은 표준 NTCP I2NP 헤더의 첫 9바이트를 사용하고, 다음과 같이 헤더의 마지막 7바이트를 제거합니다: 만료 시간을 8바이트에서 4바이트로 자르고, 2바이트 길이를 제거하며(블록 크기 - 9를 사용), 1바이트 SHA256 체크섬을 제거합니다.
+----+----+----+----+----+----+----+----+
| 3 | size |type| msg id |
+----+----+----+----+----+----+----+----+
| short exp | message |
+----+----+----+----+ +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
blk :: 3
size :: 2 bytes, big endian, size of type + msg id + exp + message to follow
I2NP message body size is (size - 9).
type :: 1 byte, I2NP msg type, see I2NP spec
msg id :: 4 bytes, big endian, I2NP message ID
short exp :: 4 bytes, big endian, I2NP message expiration, Unix timestamp, unsigned seconds.
Wraps around in 2106
message :: I2NP message body
Notes
- 구현자는 블록을 읽을 때 잘못된 형식이거나 악의적인 데이터로 인해 읽기 작업이 다음 블록으로 넘어가지 않도록 보장해야 합니다.
2) SessionCreated
Noise는 명시적인 종료 메시지를 권장합니다. 원래 NTCP에는 이것이 없습니다. 연결을 끊습니다. 이것은 프레임에서 마지막 비패딩 블록이어야 합니다.
+----+----+----+----+----+----+----+----+
| 4 | size | valid data frames |
+----+----+----+----+----+----+----+----+
received | rsn| addl data |
+----+----+----+----+ +
~ . . . ~
+----+----+----+----+----+----+----+----+
blk :: 4
size :: 2 bytes, big endian, value = 9 or more
valid data frames received :: The number of valid AEAD data phase frames received
(current receive nonce value)
0 if error occurs in handshake phase
8 bytes, big endian
rsn :: reason, 1 byte:
0: normal close or unspecified
1: termination received
2: idle timeout
3: router shutdown
4: data phase AEAD failure
5: incompatible options
6: incompatible signature type
7: clock skew
8: padding violation
9: AEAD framing error
10: payload format error
11: message 1 error
12: message 2 error
13: message 3 error
14: intra-frame read timeout
15: RI signature verification fail
16: s parameter missing, invalid, or mismatched in RouterInfo
17: banned
addl data :: optional, 0 or more bytes, for future expansion, debugging,
or reason text.
Format unspecified and may vary based on reason code.
Notes
모든 이유가 실제로 사용되는 것은 아니며, 구현에 따라 다릅니다. 핸드셰이크 실패는 일반적으로 TCP RST로 연결을 닫는 결과를 가져옵니다. 위의 핸드셰이크 메시지 섹션의 주석을 참조하세요. 나열된 추가 이유들은 일관성, 로깅, 디버깅 또는 정책 변경을 위한 것입니다.
Padding
이는 AEAD 프레임 내부의 패딩을 위한 것입니다. 메시지 1과 2의 패딩은 AEAD 프레임 외부에 있습니다. 메시지 3과 데이터 단계의 모든 패딩은 AEAD 프레임 내부에 있습니다.
AEAD 내부의 패딩은 협상된 매개변수를 대략적으로 준수해야 합니다. Bob은 메시지 2에서 요청한 tx/rx 최소/최대 매개변수를 전송했습니다. Alice는 메시지 3에서 요청한 tx/rx 최소/최대 매개변수를 전송했습니다. 업데이트된 옵션은 데이터 단계 중에 전송될 수 있습니다. 위의 옵션 블록 정보를 참조하세요.
존재하는 경우, 이는 프레임의 마지막 블록이어야 합니다.
+----+----+----+----+----+----+----+----+
|254 | size | padding |
+----+----+----+ +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
blk :: 254
size :: 2 bytes, big endian, size of padding to follow
padding :: random data
Notes
- 패딩 전략은 미정입니다.
- 최소 패딩은 미정입니다.
- 패딩 전용 프레임이 허용됩니다.
- 패딩 기본값은 미정입니다.
- 패딩 매개변수 협상에 대해서는 옵션 블록을 참조하세요
- 최소/최대 패딩 매개변수에 대해서는 옵션 블록을 참조하세요
- Noise는 메시지를 64KB로 제한합니다. 더 많은 패딩이 필요한 경우 여러 프레임을 전송하세요.
- 협상된 패딩 위반에 대한 router 응답은 구현에 따라 다릅니다.
Other block types
구현체들은 순방향 호환성을 위해 알 수 없는 블록 타입들을 무시해야 하며, 메시지 3 파트 2에서는 알 수 없는 블록이 허용되지 않는 경우를 제외합니다.
Future work
- 패딩 길이는 메시지별로 결정되고 길이 분포를 추정하거나, 무작위 지연이 추가되어야 합니다. 이러한 대응책은 DPI에 대응하기 위해 포함되어야 하며, 그렇지 않으면 메시지 크기가 전송 프로토콜에 의해 I2P 트래픽이 전달되고 있음을 드러낼 수 있습니다. 정확한 패딩 방식은 향후 작업 영역이며, 부록 A에서 이 주제에 대한 더 많은 정보를 제공합니다.
5) Termination
연결은 일반적인 또는 비정상적인 TCP 소켓 종료를 통해 종료될 수 있으며, Noise가 권장하는 바와 같이 명시적인 종료 메시지를 통해서도 종료될 수 있습니다. 명시적인 종료 메시지는 위의 데이터 단계에서 정의됩니다.
정상적이거나 비정상적인 종료 시에, router들은 핸드셰이크 ephemeral 키, 대칭 암호화 키, 그리고 관련 정보를 포함하여 메모리 내의 모든 ephemeral 데이터를 제로화해야 합니다.
Published Router Info
핸드셰이크 메시지 3 파트 1에 대한 암호화, 메시지 2 KDF 사용)
게시된 RouterAddress(RouterInfo의 일부)는 “NTCP” 또는 “NTCP2"의 프로토콜 식별자를 가집니다.
RouterAddress는 현재 NTCP 프로토콜에서와 같이 “host"와 “port” 옵션을 포함해야 합니다.
RouterAddress는 NTCP2 지원을 나타내기 위해 세 개의 옵션을 포함해야 합니다:
s=(Base64 key) 이 RouterAddress에 대한 현재 Noise 정적 공개 키(s)입니다. 표준 I2P Base 64 알파벳을 사용하여 Base 64로 인코딩됩니다. 바이너리로 32바이트, Base 64로 인코딩했을 때 44바이트, 리틀 엔디안 X25519 공개 키입니다.
i=(Base64 IV) 이 RouterAddress에 대한 메시지 1의 X 값을 암호화하기 위한 현재 IV입니다. 표준 I2P Base 64 알파벳을 사용하여 Base 64로 인코딩됩니다. 바이너리로 16바이트, Base 64 인코딩으로 24바이트, 빅엔디안입니다.
v=2 현재 버전 (2). “NTCP"로 게시될 때, 버전 1에 대한 추가 지원이 암시됩니다. 향후 버전에 대한 지원은 쉼표로 구분된 값으로 표시됩니다, 예: v=2,3 구현은 쉼표가 있을 경우 여러 버전을 포함하여 호환성을 확인해야 합니다. 쉼표로 구분된 버전은 숫자 순서로 나열되어야 합니다.
Alice는 NTCP2 프로토콜을 사용하여 연결하기 전에 세 가지 옵션이 모두 존재하고 유효한지 확인해야 합니다.
“s”, “i”, “v” 옵션과 함께 “NTCP"로 게시될 때, router는 해당 호스트와 포트에서 NTCP 및 NTCP2 프로토콜 모두에 대한 수신 연결을 수락해야 하며, 프로토콜 버전을 자동으로 감지해야 합니다.
“s”, “i”, “v” 옵션과 함께 “NTCP2"로 게시될 때, 라우터는 해당 호스트와 포트에서 NTCP2 프로토콜에 대해서만 들어오는 연결을 허용합니다.
router가 NTCP1과 NTCP2 연결을 모두 지원하지만 들어오는 연결에 대한 자동 버전 감지를 구현하지 않는 경우, “NTCP"와 “NTCP2” 주소를 모두 광고해야 하며, “NTCP2” 주소에만 NTCP2 옵션을 포함해야 합니다. router는 NTCP2가 선호되도록 “NTCP2” 주소에 “NTCP” 주소보다 낮은 비용 값(더 높은 우선순위)을 설정해야 합니다.
동일한 RouterInfo에 여러 NTCP2 RouterAddress(“NTCP” 또는 “NTCP2"로)가 게시되는 경우(추가 IP 주소나 포트를 위해), 동일한 포트를 지정하는 모든 주소는 동일한 NTCP2 옵션과 값을 포함해야 합니다. 특히, 모든 주소는 동일한 정적 키와 iv를 포함해야 합니다.
Key Derivation Function (KDF) (핸드셰이크 메시지 3 파트 2용)
Alice가 들어오는 연결을 위해 자신의 NTCP2 주소를 (“NTCP” 또는 “NTCP2"로) 공개하지 않는 경우, Bob이 메시지 3 파트 2에서 Alice의 RouterInfo를 수신한 후 키를 검증할 수 있도록 정적 키와 NTCP2 버전만을 포함하는 “NTCP2” router 주소를 공개해야 합니다.
s=(Base64 키) 위에서 게시된 주소에 대해 정의된 바와 같습니다.
v=2 위에서 게시된 주소에 대해 정의된 대로.
이 router 주소는 아웃바운드 NTCP2 연결에 필요하지 않으므로 “i”, “host” 또는 “port” 옵션을 포함하지 않습니다. 이 주소의 공개된 비용은 인바운드 전용이므로 엄격히 중요하지 않지만, 다른 주소보다 비용이 더 높게(우선순위가 낮게) 설정되면 다른 router에게 도움이 될 수 있습니다. 권장 값은 14입니다.
Alice는 기존에 게시된 “NTCP” 주소에 “s"와 “v” 옵션을 단순히 추가할 수도 있습니다.
3) SessionConfirmed
RouterInfo의 캐싱으로 인해, router는 게시된 주소에 있든 없든 router가 실행 중인 동안 정적 공개 키나 IV를 교체해서는 안 됩니다. Router는 즉시 재시작한 후 재사용할 수 있도록 이 키와 IV를 지속적으로 저장해야 하므로, 들어오는 연결이 계속 작동하고 재시작 시간이 노출되지 않습니다. Router는 시작 시 이전 다운타임을 계산할 수 있도록 마지막 종료 시간을 지속적으로 저장하거나 다른 방법으로 결정해야 합니다.
재시작 시간 노출에 대한 우려로 인해, router가 일정 시간(최소 몇 시간) 이상 중단되었다가 시작될 때 이 키나 IV를 교체할 수 있습니다.
router가 게시된 NTCP2 RouterAddress들을 가지고 있다면 (NTCP 또는 NTCP2로), 로컬 IP 주소가 변경되었거나 router가 “rekeys"하지 않는 한, 순환 전 최소 다운타임은 훨씬 길어야 하며, 예를 들어 한 달 정도여야 합니다.
라우터가 게시된 SSU RouterAddresses를 가지고 있지만 NTCP2(NTCP 또는 NTCP2로서)는 없는 경우, 로테이션 전 최소 다운타임은 더 길어야 하며, 예를 들어 하루가 되어야 합니다. 단, 로컬 IP 주소가 변경되거나 라우터가 “rekeys"하는 경우는 제외입니다. 이는 게시된 SSU 주소에 introducer가 있는 경우에도 적용됩니다.
router가 게시된 RouterAddress(NTCP, NTCP2 또는 SSU)가 없는 경우, router가 “rekeys"하지 않는 한 IP 주소가 변경되더라도 순환 전 최소 다운타임은 2시간만큼 짧을 수 있습니다.
router가 다른 Router Hash로 “rekeys"하는 경우, 새로운 noise key와 IV도 생성해야 합니다.
구현체들은 정적 공개 키나 IV를 변경하면 이전 RouterInfo를 캐시한 router들로부터의 NTCP2 연결 수신이 차단된다는 점을 인식해야 합니다. RouterInfo 게시, 터널 피어 선택(OBGW와 IB closest hop 모두 포함), 제로홉 터널 선택, 전송 선택 및 기타 구현 전략들은 이 점을 고려해야 합니다.
IV 회전은 키 회전과 동일한 규칙을 따르지만, IV는 게시된 RouterAddress에만 존재하므로 숨겨지거나 방화벽으로 보호된 router에는 IV가 없습니다. 무언가 변경되는 경우(버전, 키, 옵션?) IV도 함께 변경하는 것이 권장됩니다.
참고: 키 재생성 전 최소 다운타임은 네트워크 건전성을 보장하고, 적당한 시간 동안 다운된 router의 재시딩을 방지하기 위해 수정될 수 있습니다.
Identity Hiding
부인가능성은 목표가 아닙니다. 위의 개요를 참조하십시오.
각 패턴에는 initiator의 정적 공개 키와 responder의 정적 공개 키에 제공되는 기밀성을 설명하는 속성이 할당됩니다. 기본 가정은 임시 개인 키가 안전하며, 당사자들이 신뢰하지 않는 상대방의 정적 공개 키를 받으면 핸드셰이크를 중단한다는 것입니다.
이 섹션은 핸드셰이크의 정적 공개 키 필드를 통한 신원 유출만을 고려합니다. 물론 Noise 참여자들의 신원은 페이로드 필드, 트래픽 분석, 또는 IP 주소와 같은 메타데이터를 포함한 다른 수단을 통해 노출될 수 있습니다.
Alice: (8) 인증된 상대방에게 전방향 보안으로 암호화됨.
Bob: (3) 전송되지 않지만, 수동적 공격자가 응답자의 개인 키 후보들을 확인하여 해당 후보가 올바른지 판단할 수 있습니다.
Bob은 자신의 정적 공개 키를 netDb에 게시합니다. Alice는 그렇게 할 수도 있고 하지 않을 수도 있습니다?
Issues
- Bob이 자신의 정적 키를 변경한다면, “XX” 패턴으로 폴백할 수 있을까?
Noise Protocol Framework
“NTCP"로 게시될 때, router는 들어오는 연결에 대한 프로토콜 버전을 자동으로 감지해야 합니다.
이러한 탐지는 구현에 따라 달라지지만, 다음은 일반적인 지침입니다.
들어오는 NTCP 연결의 버전을 감지하기 위해 Bob은 다음과 같이 진행합니다:
최소 64바이트 대기 (최소 NTCP2 메시지 1 크기)
초기 수신 데이터가 288바이트 이상이면, 수신 연결은 버전 1입니다.
288바이트 미만이면, 다음 중 하나
더 많은 데이터를 위해 짧은 시간 대기 (광범위한 NTCP2 채택 이전의 좋은 전략) 총 288바이트 이상 수신된 경우, NTCP 1입니다.
버전 2로 디코딩의 첫 번째 단계를 시도하고, 실패하면 더 많은 데이터를 위해 잠시 대기 (NTCP2가 광범위하게 채택된 후 좋은 전략)
- Decrypt the first 32 bytes (the X key) of the SessionRequest packet using AES-256 with key RH_B. - Verify a valid point on the curve. If it fails, wait a short time for more data for NTCP 1 - Verify the AEAD frame. If it fails, wait a short time for more data for NTCP 1
NTCP 1에서 활성 TCP 세그멘테이션 공격이 탐지될 경우 변경 사항이나 추가 전략이 권장될 수 있음을 참고하십시오.
빠른 버전 감지 및 핸드셰이킹을 용이하게 하기 위해, 구현체는 Alice가 패딩을 포함한 첫 번째 메시지의 전체 내용을 버퍼링한 다음 한 번에 플러시하도록 보장해야 합니다. 이는 데이터가 단일 TCP 패킷에 포함될 가능성을 높이고(OS나 미들박스에 의해 분할되지 않는 한), Bob이 모든 데이터를 한 번에 받을 수 있도록 합니다. 이는 또한 효율성을 위해서이며 랜덤 패딩의 효과를 보장하기 위한 것입니다. 이는 NTCP 및 NTCP2 핸드셰이크 모두에 적용됩니다.
프레임워크에 대한 추가사항
Alice와 Bob이 모두 NTCP2를 지원하는 경우, Alice는 NTCP2로 연결해야 합니다.
Alice가 어떤 이유로든 NTCP2를 사용하여 Bob에 연결하는데 실패하면, 연결이 실패합니다. Alice는 NTCP 1을 사용하여 재시도할 수 없습니다.
Bob이 키를 변경할 경우 XX 패턴으로 폴백? 이는 타입 바이트가 앞에 추가되어야 함?
Alice가 재연결할 때 Bob이 여전히 그녀의 static key를 가지고 있다고 가정하고 KK 패턴으로 “Fall forward"할까요? 이는 round trip을 절약하지 못하고 XK의 3번 대신 4번의 DH round를 사용합니다. 아마 아닐 것입니다.
KK(s, rs):
-> s
<- s
...
-> e, es, ss
<- e, ee, se
I2P를 위한 새로운 암호화 기본 요소
이 섹션에서는 일반적인 패딩 방식에 대한 공격을 논의하는데, 이는 공격자가 패딩된 메시지의 길이만 관찰하여 패딩되지 않은 메시지 길이의 확률 분포를 발견할 수 있게 하는 공격입니다. N을 패딩되지 않은 바이트 수를 나타내는 확률변수라 하고, P를 패딩 바이트 수를 나타내는 확률변수라 하겠습니다. 그러면 전체 메시지 크기는 N + P가 됩니다.
패딩되지 않은 크기가 n일 때, 패딩 방식에서 최소 P_min(n) >= 0 바이트, 최대 P_max(n) >= P_min(n) 바이트의 패딩이 추가된다고 가정합니다. 명백한 방식은 무작위로 균등하게 선택된 길이 P의 패딩을 사용합니다:
Pr[P = p | N = n] = 1 / (P_max(n) - P_min(n)) if P_min(n) <= p <= P_max(n),
0 otherwise.
단순한 패딩 방식은 패딩된 메시지의 크기가 N_max를 초과하지 않도록 하는 것입니다:
P_max(n) = N_max - n, n <= N_max
P_min(n) = 0.
하지만 이것은 패딩되지 않은 길이에 대한 정보를 누출합니다.
공격자는 예를 들어 히스토그램을 통해 Pr[x <= N + P <= y]를 쉽게 추정할 수 있습니다.
- 이로부터 그는
Pr[n_1 <= N <= n_2]를 추정하려고 시도할 수도 있습니다:
Pr[N + P = m] = Σ_n Pr[N = n] Pr[P = m - n | N = n].
단순한 방식에서는,
Pr[N + P = m] = Σ_{n <= m} Pr[N = n] / (N_max - n).
위의 계산을 수행하기 전에도 꽤 명백했듯이, 이는 Pr[N = n]에 대한 정보를 누출합니다: 패킷의 길이가 거의 항상 m보다 크다면, N + P <= m은 거의 관찰되지 않을 것입니다. 비록 최소 메시지 길이를 관찰할 수 있다는 것 자체가 문제로 간주될 수 있지만, 이것이 가장 큰 문제는 아닙니다.
더 큰 문제는 Pr[N = n]을 정확히 결정하는 것이 가능하다는 것입니다:
Pr[N + P = m] - Pr[N + P = m-1] = Pr[N = m] / (N_max - m),
즉
Pr[N = n] = (N_max - n)(Pr[N + P = n] - Pr[N + P = n - 1])
NTCP2를 구별하기 위해 공격자는 다음 중 아무것이나 사용할 수 있습니다:
양의 정수 k에 대해
Pr[kB <= N <= (k + 1)B - 1]을 추정합니다. NTCP2의 경우 항상 0이 됩니다.Pr[N = kB]를 추정하고 표준 I2P 프로파일과 비교한다.
이 간단한 공격은 따라서 패딩되지 않은 메시지의 크기 분포를 난독화하려는 패딩의 목적을 부분적으로 파괴합니다. 공격자가 프로토콜을 구별하기 위해 관찰해야 하는 메시지의 양은 원하는 정확도와 실제로 발생하는 패딩되지 않은 메시지의 최소 및 최대 크기에 따라 달라집니다. 공격자가 대상이 사용하는 특정 포트로 송수신되는 모든 트래픽을 사용할 수 있기 때문에 공격자가 많은 메시지를 수집하는 것은 쉽다는 점에 주목하십시오.
일부 형태(예: Pr[kB <= N <= (k + 1)B - 1] 추정)에서 이 공격은 메모리를 몇 바이트만 필요로 하며(정수 하나면 충분), 이러한 공격은 약간 더 고급이지만 여전히 표준적인 DPI 프레임워크에 포함될 수 있다고 주장할 수 있습니다.
이 제안서는 다음 대응책 중 하나를 사용할 것을 제안합니다:
비균등 패딩 길이 분포를 사용하여 N의 (추정된) 분포를 고려하는 대안적 패딩 스킴을 개발한다. 좋은 패딩 스킴은 아마도 메시지당 블록 수의 히스토그램을 유지해야 할 것이다.
메시지의 (무작위 크기) 조각들 사이에 무작위 지연을 추가합니다.
두 번째 옵션이 일반적으로 더 선호되는데, 이는 플로우 분석에 대한 대응책으로도 동시에 사용될 수 있기 때문입니다. 그러나 이러한 지연은 NTCP2 프로토콜의 범위를 벗어날 수 있으므로, 구현하기도 더 쉬운 첫 번째 옵션이 대신 선호될 수 있습니다.
처리 오버헤드 추정
타이밍 기반 DPI 저항 (메시지 간 타이밍/지연은 구현에 따라 달라질 수 있으며, 메시지 내 지연은 예를 들어 랜덤 패딩을 보내기 전을 포함하여 어느 시점에서든 도입될 수 있음). 인위적 지연 (obfs4가 IAT 또는 도착 간격 시간이라고 부르는 것)은 프로토콜 자체와는 독립적입니다.