เหตุใดจึงต้องใช้คีย์ API และความลับ


93

ฉันเจอ API มากมายที่ให้ทั้งคีย์ API และความลับแก่ผู้ใช้ แต่คำถามของฉันคืออะไรคือความแตกต่างระหว่างทั้งสอง?

ในสายตาของฉันกุญแจดอกเดียวก็เพียงพอแล้ว สมมติว่าฉันมีคีย์และมีเพียงฉันและเซิร์ฟเวอร์เท่านั้นที่รู้ ฉันสร้างแฮช HMAC ด้วยคีย์นี้และทำการเรียก API บนเซิร์ฟเวอร์เราสร้างแฮช HMAC อีกครั้งและเปรียบเทียบกับแฮชที่ส่ง หากเหมือนกันแสดงว่ามีการตรวจสอบสิทธิ์การโทร

ทำไมต้องใช้สองปุ่ม?

แก้ไข:หรือคีย์ API นั้นใช้เพื่อค้นหาข้อมูลลับของ API หรือไม่


คำตอบ:


47

การเข้ารหัสคีย์ลับอาศัยการใช้คีย์เดียวกันในการเข้ารหัสจากนั้นจึงถอดรหัสข้อความในภายหลัง ดังนั้นเฉพาะผู้ที่ทราบ "ความลับ" เท่านั้นที่สามารถอ่านข้อความได้

การรักษาความปลอดภัย RSA ขึ้นอยู่กับ 2 คีย์ที่ตรงกัน มีคีย์สาธารณะสำหรับผู้ใช้แต่ละคนและทุกคนสามารถ (ควร) รู้ได้ นอกจากนี้ยังมีคีย์ส่วนตัวที่เฉพาะผู้ใช้เท่านั้นที่ควรรู้ ข้อความที่เข้ารหัสด้วยคีย์สาธารณะสามารถถอดรหัสได้ด้วยคีย์ส่วนตัวเท่านั้นและในทางกลับกันวีซ่า

ดังนั้นหากฉันต้องการส่งข้อความที่มีคุณเท่านั้นที่สามารถอ่านได้ฉันจะได้รับ (จากเครือข่าย) คีย์สาธารณะของคุณเข้ารหัสข้อความด้วยคีย์นั้นและคุณเป็นคนเดียวที่ถอดรหัสได้

หรือถ้าฉันต้องการพิสูจน์ให้คุณเห็นว่าฉันส่งข้อความไปฉันสามารถเข้ารหัสข้อความด้วยคีย์ส่วนตัวของฉันบอกคุณ (ในข้อความเปิดหรือในข้อความอื่น) ว่ามันเข้ารหัสอย่างไร จากนั้นคุณสามารถถอดรหัสข้อความด้วยคีย์สาธารณะของฉันและถ้าอ่านได้คุณก็รู้ว่ามันมาจากฉัน

การเข้ารหัสรูปแบบนี้ใช้คอมพิวเตอร์ค่อนข้างเข้มข้นดังนั้นบางครั้งสิ่งที่ทำได้คือเข้ารหัส "คีย์ลับ" แบบครั้งเดียวด้วยเทคโนโลยี RSA จากนั้นเข้ารหัสข้อความที่เหลือด้วยคีย์ลับจากนั้นเข้ารหัสลายเซ็นของฉันในแบบที่สอง จากนั้นคุณย้อนกระบวนการนี้ดังนั้นหากข้อความและลายเซ็นสามารถอ่านได้คุณและคุณเท่านั้นที่สามารถอ่านได้และคุณมั่นใจได้ว่าฉันส่งข้อความไปแล้ว

หรือ

คุณสามารถเยี่ยมชมลิงค์นี้เพื่อดูคำอธิบายโดยละเอียดเพิ่มเติม

คีย์ API และคีย์ลับทำงานอย่างไร


9
คำตอบที่ดี แต่เมื่อฉันใช้ความลับและคีย์ API กับ Facebook หรือ Gmail ฯลฯ ฉันไม่ต้องเข้ารหัสหรือแฮชอะไรเลย ในกรณีดังกล่าวความลับและคีย์ของ API คืออะไร
Quintonn

2
การใช้ Facebook เป็นตัวอย่างมีสองสถานการณ์ที่คุณจะใช้ app_secret อันแรกไม่ต้องมีการแฮช โดยหลักแล้วจะใช้เพื่อป้องกันไม่ให้ URL เปลี่ยนเส้นทางของคุณถูกขโมย หลังจากผู้ใช้เข้าสู่ระบบและให้สิทธิ์การเข้าถึงแอปของคุณหาก facebook ส่งโทเค็นการเข้าถึงโดยตรงไปยัง URL การเปลี่ยนเส้นทางคุณจะไม่มีทางตรวจสอบได้ว่าโทเค็นการเข้าถึงนั้นมาจาก Facebook หรือไม่ ฉันสามารถโพสต์โทเค็นการเข้าถึงของตัวเองไปยัง URL การเปลี่ยนเส้นทางของคุณและดำเนินการกับ Facebook ที่มาจาก API ของคุณ แต่ facebook จะส่งรหัสไปยัง URL การเปลี่ยนเส้นทาง จากนั้น API จะแลกเปลี่ยนรหัสสำหรับโทเค็นการเข้าถึงจริง
Ryan Thomas

2
ในช่วงหลังการแลกเปลี่ยนรหัสสำหรับโทเค็นการเข้าถึงจริง facebook คาดว่า api ของคุณจะยืนยันตัวตนด้วยลายเซ็น ในสถานการณ์นี้พวกเขาไม่ต้องการการเข้ารหัสคีย์สาธารณะในการเซ็นชื่อพวกเขาเพียงแค่ไว้วางใจให้คุณเก็บแอปของคุณเป็นความลับอย่างแท้จริงและใช้เป็นลายเซ็นของคุณ สิ่งนี้ดูเหมือนจะไร้สาระสำหรับฉันเสมอที่จะไม่ดำเนินการต่อและใช้ฟังก์ชันทางเดียวในการสร้างลายเซ็น แต่ฉันคิดว่าพวกเขามีเหตุผลเช่นประสิทธิภาพในการตัดสินสำหรับการใช้ความลับของแอปโดยตรง
Ryan Thomas

ในกรณีการใช้งานที่สองคุณใช้การแฮชการเข้ารหัส หลังจากที่คุณมี access_token จริงเพื่อเริ่มโต้ตอบกับ facebook แล้วคุณอาจต้องการความปลอดภัยเพิ่มเติมเพื่อป้องกันไม่ให้แอปของคุณถูกแอบอ้าง ในคอนโซลแอพ Facebook คุณสามารถเปิดฟีเจอร์ที่ต้องใช้ทุกคำขอของ facebook api จากแอพของคุณเพื่อรวมลายเซ็นของคุณนอกเหนือจากโทเค็นการเข้าถึง ฉันแค่คาดเดาแรงจูงใจของพวกเขา แต่ฉันคิดว่า ณ จุดนี้พวกเขาไม่ต้องการให้คุณส่ง app_secret ซ้ำ ๆ เป็นลายเซ็นในทุกคำขอ ยิ่งส่งมากโอกาสที่ app_secret จะถูกบุกรุกก็ยิ่งมากขึ้น
Ryan Thomas

1
ฉันคิดว่าเนื่องจากคุณได้เลือกใช้คุณสมบัติความปลอดภัยเพิ่มเติมนี้คุณได้ตัดสินใจหลายอย่างเพื่อให้ Facebook สามารถตรวจสอบลายเซ็นของคุณได้โดยใช้แฮชที่เข้ารหัสลับ อย่างไรก็ตามในสถานการณ์นี้คุณส่งผ่านค่าสองค่าพร้อมคำขอ API ของ Facebook access_token และค่าที่ชื่อ appsecret_proof ซึ่งทำหน้าที่เป็นลายเซ็นของคุณ การพิสูจน์ความลับของแอปสร้างขึ้นโดยการแฮชการเข้ารหัสของ access_token โดยใช้ app_secret เป็นกุญแจสำคัญ
Ryan Thomas

55

คุณจำเป็นต้องมีสองปุ่มแยกหนึ่งที่จะบอกพวกเขาว่าคุณเป็นใครและคนอื่น ๆ ที่พิสูจน์ให้เห็นว่าคุณเป็นใครคุณบอกว่าคุณเป็น

"คีย์" คือรหัสผู้ใช้ของคุณและ "ความลับ" คือรหัสผ่านของคุณ พวกเขาเพียงแค่ใช้คำว่า "คีย์" และ "ความลับ" เพราะเป็นวิธีที่ใช้


1
แล้วถ้าคุณสื่อสารผ่าน https ล่ะ? อะไรคือจุดสำคัญของการเข้ารหัสข้อความของคุณด้วยคีย์ลับ?
kamuniaft

6
ประเด็นอยู่เสมอเพื่อลดความเสี่ยง หากการสื่อสาร https ถูกบุกรุกผู้โจมตีที่สามารถอ่านคำขอของคุณจะไม่สามารถปลอมแปลงใหม่ได้ หาก API ของคุณกำลังจะจัดอันดับรูปภาพของแมวไม่ใช่เรื่องใหญ่หากเป็น API การชำระเงินคุณควรมีการรักษาความปลอดภัยหลายชั้นดีกว่า :)
Yall

ฉันคิดว่าจุดประสงค์มันคือคีย์สองอันที่แยกจากกันเนื่องจากผู้ใช้ที่แตกต่างกันของแอปไคลเอนต์เดียวอาจมีความลับที่แตกต่างกันมิฉะนั้นหากพวกเขาทั้งหมดมีความลับเดียวกันการมีคีย์ก็ไม่มีประโยชน์ ขวา?
น้ำผึ้ง

เหตุใด API เหล่านี้จึงไม่ใช้การBearer:รับรองความถูกต้อง คุณจะมี ID และ pwd ที่นั่น
Stefan Haberl

7

ตอบง่ายๆถ้าเข้าใจถูก ...

หากคุณใช้คีย์ API ในการเข้ารหัสบริการจะรู้ได้อย่างไรว่าใครกำลังติดต่อพวกเขาอยู่ พวกเขาจะถอดรหัสข้อความนั้นอย่างไร?

คุณใช้คีย์ API เพื่อระบุว่าคุณเป็นใครนี่คือสิ่งที่คุณส่งเป็นข้อความธรรมดา คีย์ความลับที่คุณไม่ได้ส่งให้ใคร คุณเพียงแค่ใช้มันเพื่อเข้ารหัส จากนั้นคุณจะส่งข้อความที่เข้ารหัส คุณไม่ได้ส่งคีย์ที่ใช้ในการเข้ารหัสซึ่งจะทำให้จุดประสงค์ไม่ถูกต้อง


คุณทำ. คุณส่งคีย์ api ไปยังเซิร์ฟเวอร์ ดังนั้นหมายความว่าคุณกำลังให้คุณค่ากับใครก็ตามที่อาจขัดขวางการสื่อสารของคุณกับเซิร์ฟเวอร์
anajic

เกือบทุก API ที่ฉันเคยเห็นคุณส่งทั้งคีย์และความลับไปยังเซิร์ฟเวอร์ การเชื่อมต่อกับเซิร์ฟเวอร์ถูกเข้ารหัสด้วยความปลอดภัยระดับเดียวกันในทางทฤษฎี แต่ฉันไม่เคยให้คนอื่นนอกจากเซิร์ฟเวอร์
sudo

ฉันไม่เคยเห็นการส่งsecretข้อความธรรมดา ขอลิงค์หน่อยได้ไหม สิ่งที่ฉันเห็นคือการใช้secretเพื่อเข้ารหัสข้อมูลบางอย่าง และพร้อมกับข้อมูลที่เข้ารหัสการส่งapiKeyเพื่อให้เซิร์ฟเวอร์รู้วิธีถอดรหัสข้อมูล
Ancajic

twilio.com/docs/sms/tutorials/…และnexmo.github.io/Quickstarts/sms/sendเป็นตัวอย่างที่ฉันเห็นที่แจ้งให้ค้นหาใน StackOverflow
sudo

Twilio ไม่ได้ใช้คำเหล่านี้อย่างแน่นอน แต่ Nexmo แน่ใจว่าคือ ... แต่หลังจากที่ได้อย่างรวดเร็วก็ดูเหมือนว่าพวกเขาเป็นเพียงการเรียกข้อมูลsecretและapiKeyสิ่งที่พวกเขาทำจริงเป็นและusername passwordซึ่งเป็นสิ่งที่แตกต่างอย่างสิ้นเชิง ...
ancajic

3

มีคำตอบที่อธิบายว่าความลับและคีย์ (สาธารณะ) คืออะไร เป็นคู่คีย์สาธารณะและส่วนตัวที่พวกเขาตั้งชื่อให้สับสน แต่ไม่มีใครบอกว่าทำไม API ต้องใช้ทั้งสองอย่างและ API จำนวนมากให้ความลับเดียวกับคุณ! ฉันยังไม่เคยเห็นเอกสารของ API ใด ๆ ที่อธิบายว่าทำไมพวกเขาถึงมีสองคีย์ดังนั้นสิ่งที่ดีที่สุดที่ฉันทำได้คือการคาดเดา ...

ควรใส่เฉพาะคีย์สาธารณะในคำขอของคุณและลงนามในคำขอในเครื่องด้วยคีย์ส่วนตัวของคุณ ไม่จำเป็นต้องส่งอะไรเพิ่มเติม แต่บางคนก็หนีไปเพียงแค่มีความลับในคำขอ โอเค API ใด ๆ ที่ดีจะใช้ความปลอดภัยในการขนส่งเช่น TLS (โดยปกติจะใช้ผ่าน HTTPS) แต่คุณยังคงเปิดเผยคีย์ส่วนตัวของคุณไปยังเซิร์ฟเวอร์ด้วยวิธีนี้เพิ่มความเสี่ยงที่พวกเขาจะจัดการกับมันในทางที่ผิด (ดู: ข้อผิดพลาดการบันทึกรหัสผ่านของ GitHub และ Twitter ที่เพิ่งค้นพบ) และในทางทฤษฎี HTTPS ก็ปลอดภัยพอ ๆ กัน แต่ก็มีข้อบกพร่องในการใช้งานอยู่เสมอ

แต่ส่วนใหญ่ดูเหมือนว่า API จะส่งคีย์ทั้งสองในคำขอเนื่องจากง่ายกว่าการให้ผู้อื่นเซ็นลายเซ็นของตนเอง ไม่สามารถมีตัวอย่าง cURL ที่บริสุทธิ์เป็นอย่างอื่นได้! ในกรณีนี้มันไม่มีประโยชน์ที่จะแยกพวกเขาออกจากกัน ฉันเดาว่าคีย์แยกต่างหากมีไว้สำหรับในกรณีที่พวกเขาเปลี่ยน API ในภายหลังเพื่อใช้ประโยชน์จากคีย์เหล่านั้น หรือบางแห่งมีไลบรารีไคลเอ็นต์ที่อาจทำให้ปลอดภัยยิ่งขึ้น


1

สิ่งหนึ่งที่ฉันไม่เห็นที่กล่าวถึงในที่นี้แม้ว่าจะเป็นส่วนเสริมของคำตอบของ Marcus Adams ก็คือคุณไม่ควรใช้ข้อมูลเพียงชิ้นเดียวในการระบุและรับรองความถูกต้องของผู้ใช้หากมีความเป็นไปได้ในการโจมตีตามเวลาซึ่งสามารถ ใช้ความแตกต่างของเวลาตอบสนองเพื่อคาดเดาว่าการเปรียบเทียบสตริงไปได้ไกลแค่ไหน

หากคุณใช้ระบบที่ใช้ "คีย์" เพื่อค้นหาผู้ใช้หรือข้อมูลรับรองข้อมูลส่วนนั้นอาจถูกคาดเดาเพิ่มขึ้นเมื่อเวลาผ่านไปโดยการส่งคำขอหลายพันรายการและตรวจสอบเวลาที่ฐานข้อมูลของคุณใช้ในการค้นหา (หรือไม่ ค้นหา) บันทึก โดยเฉพาะอย่างยิ่งหาก "คีย์" ถูกเก็บไว้ในข้อความธรรมดาแทนที่จะเป็นแฮชทางเดียวของคีย์ คุณต้องการจัดเก็บคีย์ของผู้ใช้ในรูปแบบข้อความธรรมดาหรือเข้ารหัสแบบสมมาตรหากคุณต้องการให้สามารถแสดงคีย์ให้กับผู้ใช้ได้อีกครั้ง

เมื่อมีข้อมูลชิ้นที่สองหรือ "ความลับ" ก่อนอื่นคุณสามารถค้นหาผู้ใช้หรือข้อมูลรับรองโดยใช้ "คีย์" ซึ่งอาจเสี่ยงต่อการโจมตีตามเวลาจากนั้นใช้ฟังก์ชันเปรียบเทียบเวลาที่ปลอดภัยเพื่อตรวจสอบค่าของ ความลับ".

นี่คือการใช้งานฟังก์ชันนั้นของ Python:

https://github.com/python/cpython/blob/cd8295ff758891f21084a6a5ad3403d35dda38f7/Modules/_operator.c#L727

และมีการเปิดเผยใน hmac lib (และอาจเป็นอื่น ๆ ):

https://docs.python.org/3/library/hmac.html#hmac.compare_digest


สิ่งหนึ่งที่ควรทราบก็คือฉันไม่คิดว่าการโจมตีแบบนี้จะใช้ได้กับค่าที่แฮชหรือเข้ารหัสก่อนการค้นหาเนื่องจากค่าที่เปรียบเทียบจะเปลี่ยนแปลงแบบสุ่มทุกครั้งที่อักขระในสตริงอินพุตเปลี่ยนแปลง ฉันพบคำอธิบายที่ดีเกี่ยวกับเรื่องนี้ที่นี่

โซลูชันสำหรับการจัดเก็บคีย์ API จะเป็น:

  1. ใช้คีย์และความลับแยกกันใช้คีย์เพื่อค้นหาเรกคอร์ดและใช้การเปรียบเทียบเวลาที่ปลอดภัยเพื่อตรวจสอบความลับ สิ่งนี้ช่วยให้คุณสามารถแสดงรหัสและความลับแก่ผู้ใช้อีกครั้ง
  2. ใช้คีย์และความลับแยกกันใช้การเข้ารหัสแบบสมมาตรกำหนดความลับและทำการเปรียบเทียบความลับที่เข้ารหัสตามปกติ วิธีนี้ช่วยให้คุณสามารถแสดงรหัสและความลับแก่ผู้ใช้อีกครั้งและช่วยให้คุณไม่ต้องใช้การเปรียบเทียบตามเวลา
  3. ใช้คีย์และความลับแยกกันแสดงความลับแฮชและเก็บไว้จากนั้นทำการเปรียบเทียบความลับที่แฮชตามปกติ วิธีนี้จะขจัดความจำเป็นในการใช้การเข้ารหัสสองทางและมีประโยชน์เพิ่มเติมในการรักษาความลับของคุณให้ปลอดภัยหากระบบถูกบุกรุก มีข้อเสียที่คุณไม่สามารถแสดงความลับให้ผู้ใช้เห็นได้อีก
  4. ใช้คีย์เดียวแสดงให้ผู้ใช้ดูหนึ่งครั้งแฮชแล้วทำการค้นหาคีย์ที่แฮชหรือเข้ารหัสตามปกติ ซึ่งใช้คีย์เดียว แต่ไม่สามารถแสดงให้ผู้ใช้ได้เห็นอีก มีประโยชน์ในการรักษาความปลอดภัยของคีย์หากระบบถูกบุกรุก
  5. ใช้คีย์เดียวแสดงให้ผู้ใช้เห็นครั้งเดียวเข้ารหัสและทำการค้นหาข้อมูลลับที่เข้ารหัสตามปกติ สามารถแสดงให้ผู้ใช้ได้เห็นอีกครั้ง แต่ต้องเสียค่าใช้จ่ายในการมีคีย์ที่เสี่ยงหากระบบถูกบุกรุก

ในจำนวนนี้ฉันคิดว่า 3 คือความสมดุลของความปลอดภัยและความสะดวกสบายที่ดีที่สุด ฉันเห็นสิ่งนี้ถูกนำไปใช้ในหลาย ๆ เว็บไซต์เมื่อได้รับคีย์

นอกจากนี้ฉันเชิญผู้เชี่ยวชาญด้านความปลอดภัยที่แท้จริงให้วิจารณ์คำตอบนี้ ฉันแค่อยากจะเอาสิ่งนี้ออกไปเป็นประเด็นสนทนาอื่น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.