แนวทางที่ดีที่สุดในการสร้างคีย์ API ใหม่คืออะไร


92

ดังนั้นด้วยบริการที่แตกต่างกันมากมายในตอนนี้ Google APIs, Twitter API, Facebook API และอื่น ๆ

แต่ละบริการมีคีย์ API เช่น:

AIzaSyClzfrOzB818x55FASHvX4JuGQciR9lv7q

คีย์ทั้งหมดมีความยาวและอักขระที่แตกต่างกันไปฉันสงสัยว่าวิธีที่ดีที่สุดในการสร้างคีย์ API คืออะไร?

ฉันไม่ได้ขอภาษาใดภาษาหนึ่งเป็นเพียงวิธีการทั่วไปในการสร้างคีย์หากเป็นการเข้ารหัสรายละเอียดของแอปผู้ใช้หรือแฮชหรือแฮชของสตริงแบบสุ่ม ฯลฯ เราควรกังวลเกี่ยวกับอัลกอริทึมแฮช (MSD, SHA1, bcrypt) ฯลฯ ?

แก้ไข: ฉันได้พูดคุยกับเพื่อนสองสามคน (อีเมล / ทวิตเตอร์) และพวกเขาแนะนำให้ใช้ GUID โดยมีเครื่องหมายขีดกลาง

ดูเหมือนว่าจะเป็นเรื่องเล็กน้อยสำหรับฉัน แต่หวังว่าจะได้รับแนวคิดเพิ่มเติม


ฉันได้ตอบรายละเอียดเพิ่มเติมที่นี่แล้ว .. การสร้างคีย์และใช้เป็น hmac auth
Anshu Kumar

คำตอบ:


59

ใช้ตัวสร้างตัวเลขสุ่มที่ออกแบบมาสำหรับการเข้ารหัส จากนั้นฐาน -64 เข้ารหัสหมายเลข

นี่คือตัวอย่าง C #:

var key = new byte[32];
using (var generator = RandomNumberGenerator.Create())
    generator.GetBytes(key);
string apiKey = Convert.ToBase64String(key);

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

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

ทางออกที่ดี แต่คุณต้องมีคีย์เวิร์ด var ก่อน apiKey อาจจะ :) var apiKey = Convert ToBase64String (คีย์);
Dawid Ohia

@ JohnM2 ขวา ฉันปล่อยให้มันเป็นแบบปลายเปิดเนื่องจากapiKeyสามารถประกาศที่อื่นได้ ฉันเพิ่มประเภทเพื่อความชัดเจน
Edward Brey

4
@JamesWierzba หากการโจมตีอยู่ในฐานข้อมูลของคุณแล้วการเข้าถึง API ของคุณที่ไม่มีหลักประกันอาจเป็นเรื่องที่คุณกังวลน้อยที่สุด ...
Jon Story

30

คีย์ API ต้องมีคุณสมบัติที่:

  • ระบุผู้ใช้ API ที่ได้รับอนุญาตโดยไม่ซ้ำกัน - ส่วน "คีย์" ของ "คีย์ API"
  • รับรองความถูกต้องของผู้ใช้นั้น - ไม่สามารถคาดเดา / ปลอมแปลงได้
  • สามารถเพิกถอนได้หากผู้ใช้ทำงานผิดปกติ - โดยทั่วไปแล้วพวกเขาจะป้อนข้อมูลในฐานข้อมูลที่สามารถลบบันทึกได้

โดยปกติคุณจะมีคีย์ API หลายพันหรือหลายล้านคีย์ไม่ใช่เป็นพันล้านคีย์ดังนั้นจึงไม่จำเป็นต้อง:

  • เก็บข้อมูลเกี่ยวกับผู้ใช้ API ได้อย่างน่าเชื่อถือเนื่องจากสามารถเก็บไว้ในฐานข้อมูลของคุณได้

ด้วยเหตุนี้วิธีหนึ่งในการสร้างคีย์ API คือการรับข้อมูลสองส่วน:

  1. หมายเลขซีเรียลเพื่อรับประกันความเป็นเอกลักษณ์
  2. บิตสุ่มเพียงพอที่จะกดคีย์ออก

และลงนามโดยใช้ความลับส่วนตัว

ตัวนับรับประกันว่าพวกเขาระบุผู้ใช้โดยไม่ซ้ำกันและการลงนามป้องกันการปลอมแปลง การเพิกถอนต้องตรวจสอบว่าคีย์ยังคงถูกต้องในฐานข้อมูลก่อนที่จะดำเนินการใด ๆ ที่ต้องมีการอนุญาตคีย์ API

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


หรือแฮชของสตริงสุ่ม

การแฮชไม่ได้ป้องกันการปลอมแปลง การลงนามคือสิ่งที่รับประกันว่ากุญแจมาจากคุณ


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

3
@sappenin ใช่ หากคุณเก็บคีย์ที่ไม่สามารถเข้าใจได้บนเซิร์ฟเวอร์คุณก็ไม่จำเป็นต้องป้องกันการปลอมแปลง บ่อยครั้งที่การร้องขอ API ได้รับการจัดการโดยหนึ่งในฟาร์มของเครื่องใด ๆ - เซิร์ฟเวอร์เป็นหนึ่งในหลายเซิร์ฟเวอร์ การตรวจสอบลายเซ็นสามารถทำได้บนเครื่องใดก็ได้โดยไม่ต้องไป - กลับฐานข้อมูลซึ่งสามารถหลีกเลี่ยงสภาวะการแข่งขันได้ในบางกรณี
Mike Samuel

1
@MikeSamuel หากคีย์ API ถูกเซ็นชื่อและคุณไม่ได้เดินทางไปยังฐานข้อมูลจะเกิดอะไรขึ้นเมื่อคีย์ถูกเพิกถอน แต่ยังคงใช้เพื่อเข้าถึง API
Abhyudit Jain

@AbhyuditJain ในระบบกระจายใด ๆ คุณต้องมีลำดับข้อความที่สอดคล้องกัน (การเพิกถอนจะเกิดขึ้นก่อนการใช้ข้อมูลรับรองที่ถูกเพิกถอนในภายหลัง) หรือวิธีอื่น ๆ ในการผูกความคลุมเครือ บางระบบไม่สามารถไป - กลับได้ในทุกคำขอ - หากโหนดเก็บข้อมูลว่าคีย์อยู่ในฐานข้อมูลเป็นเวลา 10 นาทีจะมีเวลาเพียง 10 นาที หน้าต่างที่ผู้โจมตีสามารถละเมิดข้อมูลประจำตัวที่ถูกเพิกถอน อาจเกิดความสับสนได้: ผู้ใช้เพิกถอนข้อมูลรับรองจากนั้นทดสอบว่าเพิกถอนแล้วและรู้สึกประหลาดใจเนื่องจากเซสชันที่ไม่ติดหนึบทำให้คำขอทั้งสองไปยังโหนดที่ต่างกัน
Mike Samuel

5

ฉันใช้ UUID ซึ่งจัดรูปแบบเป็นตัวพิมพ์เล็กโดยไม่มีขีดกลาง

การสร้างเป็นเรื่องง่ายเนื่องจากภาษาส่วนใหญ่มีอยู่ในตัว

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


15
อย่าคิดว่า UUID นั้นยากที่จะคาดเดา ไม่ควรใช้เป็นความสามารถในการรักษาความปลอดภัย (ข้อมูลจำเพาะ UUID RFC4122 ส่วนที่ 6 ) คีย์ API ต้องการจำนวนสุ่มปลอดภัย แต่UUIDs ไม่ได้ unguessable
Edward Brey

3
@EdwardBrey แล้วUUID uuid = UUID.randomUUID();ใน Java ล่ะ? คุณกำลังบอกว่าการสุ่มนั้นไม่ดีพอหรือ?
ไมโคร

8
@MicroR UUID แบบสุ่มจะปลอดภัยก็ต่อเมื่อตัวสร้างตัวเลขสุ่มที่ใช้ในการทำให้ปลอดภัยด้วยการเข้ารหัสและ 128 บิตก็เพียงพอแล้ว แม้ว่า UUID RFC จะไม่ต้องการตัวสร้างตัวเลขสุ่มที่ปลอดภัย แต่การใช้งานที่กำหนดนั้นสามารถใช้งานได้ฟรี ในกรณีของrandomUUIDเอกสาร API จะระบุโดยเฉพาะว่าใช้ "ตัวสร้างตัวเลขสุ่มหลอกที่มีการเข้ารหัสที่แข็งแกร่ง" เพื่อให้การใช้งานเฉพาะนั้นปลอดภัยสำหรับคีย์ API แบบ 128 บิต
Edward Brey

4

หากคุณต้องการคีย์ API ที่มีอักขระที่เป็นตัวเลขและตัวอักษรเท่านั้นคุณสามารถใช้วิธีการสุ่มแบบ base64โดยใช้การเข้ารหัสพื้นฐาน 62 แทน ฐาน-62 เข้ารหัสอยู่บนพื้นฐานนี้

public static string CreateApiKey()
{
    var bytes = new byte[256 / 8];
    using (var random = RandomNumberGenerator.Create())
        random.GetBytes(bytes);
    return ToBase62String(bytes);
}

static string ToBase62String(byte[] toConvert)
{
    const string alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    BigInteger dividend = new BigInteger(toConvert);
    var builder = new StringBuilder();
    while (dividend != 0) {
        dividend = BigInteger.DivRem(dividend, alphabet.Length, out BigInteger remainder);
        builder.Insert(0, alphabet[Math.Abs(((int)remainder))]);
    }
    return builder.ToString();
}

1

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

Windows เวอร์ชันก่อนหน้านี้ได้สร้าง GUID ที่คาดเดาได้เป็นต้น แต่นี่เป็นเรื่องเก่า


4
Windows 2000 เปลี่ยนไปใช้ guid ของตัวเลขสุ่ม อย่างไรก็ตามไม่มีการรับประกันว่าจะไม่สามารถทำนายตัวเลขแบบสุ่มได้ ตัวอย่างเช่นหากผู้โจมตีสร้างคีย์ API หลายคีย์ให้ตัวเองอาจเป็นไปได้ที่จะกำหนดหมายเลขสุ่มในอนาคตที่ใช้สร้างคีย์ API ของผู้ใช้รายอื่น โดยทั่วไปไม่ได้พิจารณาที่จะ UUIDs unguessable
Edward Brey
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.