เอกสารประกอบของ Shadowsocks
การเดินเรือ
กศน
กศน ย่อมาจาก Authenticated Encryption with Associated Data การเข้ารหัส AEAD มอบความลับ ความสมบูรณ์ และความถูกต้องไปพร้อม ๆ กัน พวกเขามีประสิทธิภาพที่ยอดเยี่ยมและประหยัดพลังงานบนฮาร์ดแวร์สมัยใหม่ ผู้ใช้ควรใช้รหัส AEAD ทุกครั้งที่ทำได้
ขอแนะนำให้ใช้การเข้ารหัส AEAD ต่อไปนี้ การใช้งาน Shadowsocks ที่สอดคล้องต้องรองรับ AEAD_CHACHA20_POLY1305 การใช้งานสำหรับอุปกรณ์ที่มีการเร่ง AES ด้วยฮาร์ดแวร์ ควรใช้ AEAD_AES_128_GCM และ AEAD_AES_256_GCM ด้วย
Name | นามแฝง | ขนาดคีย์ | ขนาดเกลือ | ขนาดโนเนซ | ขนาดแท็ก |
AEAD_CHACHA20_POLY1305 | chacha20-ietf-poly1305 | 32 | 32 | 12 | 16 |
AEAD_AES_256_GCM | aes-256-gcm | 32 | 32 | 12 | 16 |
AEAD_AES_128_GCM | aes-128-gcm | 16 | 16 | 12 | 16 |
โปรดดูที่ การลงทะเบียน IANA AEAD สำหรับรูปแบบการตั้งชื่อและข้อมูลจำเพาะ
ที่มาของคีย์
คีย์หลักสามารถป้อนโดยตรงจากผู้ใช้หรือสร้างจากรหัสผ่าน
HKDF_SHA1 เป็นฟังก์ชันที่ใช้คีย์ลับ เกลือที่ไม่เป็นความลับ สตริงข้อมูล และสร้างคีย์ย่อยที่มีความแข็งแกร่งในการเข้ารหัส แม้ว่าคีย์ลับอินพุตจะอ่อนแอก็ตาม
HKDF_SHA1(คีย์, เกลือ, ข้อมูล) => คีย์ย่อย
สตริงข้อมูลผูกคีย์ย่อยที่สร้างขึ้นกับบริบทของแอปพลิเคชันเฉพาะ ในกรณีของเรา สตริงต้องเป็นสตริง “ss-subkey” โดยไม่มีเครื่องหมายอัญประกาศ
เราได้รับคีย์ย่อยต่อเซสชันจากคีย์หลักที่แบ่งปันล่วงหน้าโดยใช้ HKDF_SHA1 เกลือจะต้องไม่ซ้ำกันตลอดอายุการใช้งานของมาสเตอร์คีย์ที่แบ่งปันล่วงหน้า
การเข้ารหัส / ถอดรหัสที่รับรองความถูกต้อง
AE_encrypt เป็นฟังก์ชันที่ใช้รหัสลับ ข้อความที่ไม่เป็นความลับ ข้อความ และสร้างข้อความเข้ารหัสและแท็กการตรวจสอบสิทธิ์ Nonce จะต้องไม่ซ้ำกันสำหรับคีย์ที่ระบุในการเรียกใช้แต่ละครั้ง
AE_encrypt(key, nonce, message) => (ciphertext, แท็ก)
AE_decrypt เป็นฟังก์ชันที่ใช้รหัสลับ, nonce ที่ไม่เป็นความลับ, ciphertext, แท็กการตรวจสอบสิทธิ์ และสร้างข้อความต้นฉบับ หากอินพุตใดถูกแก้ไข การถอดรหัสจะล้มเหลว
AE_decrypt(key, nonce, ciphertext, tag) => ข้อความ
TCP
สตรีม TCP ที่เข้ารหัส AEAD เริ่มต้นด้วยเกลือที่สร้างขึ้นแบบสุ่มเพื่อรับคีย์ย่อยต่อเซสชัน ตามด้วยจำนวนของชิ้นที่เข้ารหัสเท่าใดก็ได้ แต่ละก้อนมีโครงสร้างดังต่อไปนี้:
[ความยาวของเพย์โหลดที่เข้ารหัส][แท็กความยาว][เพย์โหลดที่เข้ารหัส][แท็กเพย์โหลด]
ความยาวของเพย์โหลดคือจำนวนเต็มที่ไม่ได้ลงนามแบบ big-endian ขนาด 2 ไบต์ซึ่งต่อยอดที่ 0x3FFF สองบิตที่สูงกว่าจะถูกสงวนไว้และต้องตั้งค่าเป็นศูนย์ เพย์โหลดจึงจำกัดไว้ที่ 16*1024 – 1 ไบต์
การดำเนินการเข้ารหัส/ถอดรหัส AEAD ครั้งแรกใช้การนับ nonce ที่เริ่มต้นจาก 0 หลังจากการดำเนินการเข้ารหัส/ถอดรหัสแต่ละครั้ง nonce จะเพิ่มขึ้นทีละหนึ่งราวกับว่ามันเป็นจำนวนเต็ม little-endian ที่ไม่ได้ลงนาม โปรดทราบว่าแต่ละ TCP chunk เกี่ยวข้องกับการดำเนินการเข้ารหัส/ถอดรหัส AEAD สองรายการ: หนึ่งรายการสำหรับความยาวของเพย์โหลด และอีกหนึ่งรายการสำหรับเพย์โหลด ดังนั้นแต่ละก้อนจึงเพิ่ม nonce สองครั้ง
TCP
สตรีม TCP ที่เข้ารหัส AEAD เริ่มต้นด้วยเกลือที่สร้างขึ้นแบบสุ่มเพื่อรับคีย์ย่อยต่อเซสชัน ตามด้วยจำนวนของชิ้นที่เข้ารหัสเท่าใดก็ได้ แต่ละก้อนมีโครงสร้างดังต่อไปนี้:
[ความยาวของเพย์โหลดที่เข้ารหัส][แท็กความยาว][เพย์โหลดที่เข้ารหัส][แท็กเพย์โหลด]
ความยาวของเพย์โหลดคือจำนวนเต็มที่ไม่ได้ลงนามแบบ big-endian ขนาด 2 ไบต์ซึ่งต่อยอดที่ 0x3FFF สองบิตที่สูงกว่าจะถูกสงวนไว้และต้องตั้งค่าเป็นศูนย์ เพย์โหลดจึงจำกัดไว้ที่ 16*1024 – 1 ไบต์
การดำเนินการเข้ารหัส/ถอดรหัส AEAD ครั้งแรกใช้การนับ nonce ที่เริ่มต้นจาก 0 หลังจากการดำเนินการเข้ารหัส/ถอดรหัสแต่ละครั้ง nonce จะเพิ่มขึ้นทีละหนึ่งราวกับว่ามันเป็นจำนวนเต็ม little-endian ที่ไม่ได้ลงนาม โปรดทราบว่าแต่ละ TCP chunk เกี่ยวข้องกับการดำเนินการเข้ารหัส/ถอดรหัส AEAD สองรายการ: หนึ่งรายการสำหรับความยาวของเพย์โหลด และอีกหนึ่งรายการสำหรับเพย์โหลด ดังนั้นแต่ละก้อนจึงเพิ่ม nonce สองครั้ง