2010-09-10 25 views
5

Trong suốt những ngày của tôi với tư cách là một lập trình viên PHP và người mới bắt đầu lập trình C#, tôi luôn tự hỏi cách tốt nhất để tạo ra các chuỗi duy nhất như Microsoft Office và hệ điều hành Microsoft.Thế hệ nối tiếp với PHP

Có ai có hướng dẫn tốt về cách xử lý việc này hay không, như các yếu tố quan trọng trong việc tạo chuỗi duy nhất, ngăn trùng lặp, v.v ... ví dụ nhỏ về cách tạo/xác minh chúng.

Đây là RFC tôi đang nói về: http://tools.ietf.org/html/rfc1982.

Trả lời

12

Nếu ứng dụng của bạn có kết nối trở lại máy chủ, nó chỉ cần tạo mã thông báo ngẫu nhiên, lưu trữ chúng trong cơ sở dữ liệu và yêu cầu ứng dụng kiểm tra lại với máy chủ trước khi chạy. Tuy nhiên một số khách hàng có thể thấy yêu cầu này không thể chấp nhận được. (Cá nhân tôi sẽ không bao giờ mua bất cứ phần mềm với một yêu cầu kích hoạt internet Tôi muốn mua phần mềm, không thuê nó..)

Đối với các phím với checkability xác thực mà không cần phải có một kết nối trở lại máy chủ:

  1. Trên máy chủ, tạo một mã thông báo duy nhất ngẫu nhiên.

  2. Sử dụng lược đồ mật mã khóa công khai (ví dụ: RSA) để ký mã thông báo bằng khóa riêng tư được giữ bí mật cho máy chủ.

  3. Mã hóa mã thông báo duy nhất và chữ ký với nhau bằng cách sử dụng lược đồ nhị phân thành văn bản (ví dụ: base64 hoặc chỉ sử dụng ký hiệu 2-9A-KMNP-Z để có thể đánh máy an toàn hơn). Sự kết hợp được mã hóa là khóa hoặc nối tiếp của bạn.

  4. Nhúng khóa công khai khớp với khóa riêng của máy chủ trong mỗi bản sao của ứng dụng và có lời nhắc ứng dụng cho một khóa lúc cài đặt. Nó có thể tách mã thông báo duy nhất và chữ ký và sử dụng khóa công cộng để xác minh rằng chữ ký hợp lệ cho mã thông báo đó.

Cách tiếp cận này đòi hỏi bạn bó một số thư viện crypto với phần mềm của bạn, và hầu hết các thuật toán sử dụng chữ ký khá dài, để bảo mật, mà sẽ làm cho số serial của bạn khá tẻ nhạt để gõ vào. Đó là OK nếu bạn mong đợi người dùng sao chép - và dán các số.

Vì những lý do này, nhiều gói phần mềm sử dụng lược đồ xác thực khóa kém an toàn hơn khi thuật toán kiểm tra được xây dựng hoàn toàn vào ứng dụng khách. Đây có thể là một băm, ví dụ. bốn chữ số thập phân cuối cùng của chuỗi nối tiếp phải khớp với hai byte thấp nhất của mã băm SHA1 của phần còn lại của chuỗi kết hợp với khóa ‘bí mật’. Tuy nhiên, vì khóa phải được đóng gói trong ứng dụng, nên một hacker có thể xem mã ứng dụng và trích xuất khóa ‘bí mật’, cho phép họ viết trình tạo khóa riêng của họ.

Đó là lý do tại sao đối với một số chương trình, bạn sẽ thấy ‘keygens’ khả dụng: ứng dụng đã sử dụng bản kiểm tra kém an toàn hơn, để lại đủ thông tin trong ứng dụng để cho phép trình tạo crack tạo lại quy trình tạo khóa. Đối với các chương trình có cài đặt bảo mật hơn dựa trên mật mã khóa công khai hoặc kích hoạt internet, bạn thường thấy phiên bản 'nứt' của ứng dụng thay thế, trong đó mã kiểm tra đã bị thay đổi/xóa.

... loại chứng minh rằng bất cứ điều gì bạn làm, bạn vẫn sẽ không thể thực thi sự trung thực. Vì vậy, đừng lo lắng quá nhiều về nó.

+0

Tốt tất cả các thông tin xung quanh – Fanis

+0

Hoàn hảo, Chỉ cần loại thông tin tôi đang tìm kiếm :), Rất tốt. +1 – RobertPitt

+1

: -/đây chính xác là những gì tôi đã nói. – Bot

1

Tôi không hoàn toàn chắc chắn những gì bạn muốn, nhưng có http://www.php.net/manual/en/function.uniqid.php tạo Mã định danh duy nhất.

Nếu bạn quan tâm hơn đến cách chúng được tạo, tôi khuyên bạn hãy xem nguồn PHP để xem cách uniqid được triển khai.

+0

Im nói chuyện liên quan đến http://tools.ietf.org/html/rfc1982 – RobertPitt

+0

uniqid là hoàn toàn có thể dự đoán. Trên thực tế nó chỉ là một đại diện của microtime nó đã được generatated tại. Đó là không có cách nào ngẫu nhiên. – NikiC

1

Cần thêm một chút thông tin. Bạn có muốn tạo một khóa nối tiếp như khi bạn mua một trò chơi hay bạn muốn có một chuỗi nối tiếp cho một id người dùng duy nhất.

Số sê-ri có cần lưu trữ thông tin như ngày/giờ hết hạn không?

@nikic - tất cả thời gian sử dụng của rand làm cơ sở để khởi động trình tạo ngẫu nhiên. Đó là lý do tại sao DoD sử dụng đèn dung nham. Họ có một phòng toàn bộ dành riêng cho đèn dung nham và laser tỏa sáng trên chúng để tạo ngẫu nhiên một chìa khóa duy nhất.

Đã chỉnh sửa:

Vâng những gì bạn cần có hiệu lực là phương pháp mà ứng dụng C# sẽ sử dụng để liên lạc với trang web của bạn.

Bạn sẽ cần phải tạo một khóa bằng php và lưu nó trong cơ sở dữ liệu để C# có thể xác nhận nối tiếp là chính xác.

Sau đó, bạn cần phải tìm hiểu xem PHP sẽ trả về một giá trị khác để ứng dụng C# nhận thức được khóa đã được xác thực hay chưa.

Điều tôi đã làm trong quá trình dán là tạo khóa công khai và khóa cá nhân. Khóa công khai sẽ được cung cấp cho người dùng để xác thực sản phẩm. Khi họ xác nhận sản phẩm hoặc đăng nhập vào hệ thống, khóa công khai sẽ được kiểm tra đối với cơ sở dữ liệu và giá trị trả về sẽ là khóa riêng. Trong tất cả các tương tác với chương trình C# của tôi, người dùng cần phải kiểm tra các bản cập nhật hoặc lấy thông tin từ máy chủ của tôi, khóa riêng sẽ được thêm vào truy vấn tới máy chủ để xác nhận người dùng cuối là hợp pháp.

Một phương pháp khác mà tôi cũng đã sử dụng là ở trên nhưng đã thêm kiểm tra bổ sung để xác nhận người dùng không chia sẻ khóa. Ứng dụng C# sẽ lấy số sê-ri của bộ xử lý trong máy tính và khi đăng ký ứng dụng, nó sẽ lưu nó vào cơ sở dữ liệu của tôi. Sau đó, nếu người khác cố gắng đăng ký sản phẩm với cùng một khóa công khai nhưng số sê-ri khác nhau của bộ vi xử lý thì nó sẽ gây ra lỗi và họ sẽ cần phải liên hệ với bộ phận hỗ trợ. Bạn có thể thực hiện điều này để cho phép 5 ID máy khác nhau hoặc số lượng máy bạn muốn.

Tạo khóa đăng ký rất đơn giản vì bạn thực sự chỉ cần tạo một chuỗi ngẫu nhiên có bù đắp (chẳng hạn như tên người dùng).

Bạn cũng có thể tạo khóa đăng ký dựa trên tên hoặc tên công ty mà ai đó cung cấp và thêm thuật toán đó vào chương trình C# của bạn. Nhược điểm đó là mã nguồn C# có thể được giải mã một cách dễ dàng thuật toán có thể được tìm thấy để tạo ra một mã đăng ký dễ dàng mà không có ai đó thực sự trả tiền cho sản phẩm.Bằng cách thêm vào một máy chủ thực hiện việc xác thực thì sẽ khó khăn hơn nhiều đối với ai đó để tạo ra khóa nối tiếp của riêng họ.

+0

cho phép nói rằng tôi có một sản phẩm, chẳng hạn như một ứng dụng, ứng dụng này yêu cầu một hệ thống nối tiếp, tôi muốn tạo ra một nối tiếp trong PHP có thể được kiểm tra và xác nhận trong C#, những yếu tố nào tôi phải sử dụng vào một kịch bản để có thể để tạo và xác minh khóa A bất kể thông dịch viên là gì. – RobertPitt

+0

Tôi đã chỉnh sửa câu trả lời của mình để hiển thị một số ví dụ về những gì tôi đã thực hiện trong quá trình dán. – Bot

1

Nếu bạn muốn tạo số sê-ri ngẫu nhiên ở giữa, chỉ cần tìm nạp ngẫu nhiên từ một dãy số và chữ cái là đủ. Sử dụng mt_rand(0, count($poolArray)) để nhận chỉ mục mới mỗi lần và chỉ thêm ký tự đó vào chuỗi nối tiếp của bạn cho đến khi bạn nói 12 trong số đó.

Tạo ngẫu nhiên từ một hồ bơi lớn (26 chữ số + 10 chữ số) gần như chắc chắn rằng bạn không có bản sao, nhưng bạn luôn có thể kiểm tra các bản sao hiện có trước khi lưu trữ hình mới.

Nếu bạn có 36 ký tự có thể, và bạn chọn 12 ký tự ngẫu nhiên để tạo nối tiếp, đó là 36 * 36 * 36 * ... * 36 = 36^12 = 4738381338321616896 chuỗi có thể.

$pool = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
$countPool = count($pool) ; 
$totalChars = 12 ; 

$serial = '' ; 
for ($i = 0 ; $i < $totalChars ; $i++) { 
    $currIndex = mt_rand(0, $countPool) ; 
    $currChar = $pool[$currIndex] ; 
    $serial .= $currChar ; 
} 

Phân phối mã hoặc kiểm tra chương trình nối tiếp hợp lệ của bạn là một vấn đề khác.

+0

Tôi xin lỗi, tại sao với 'count ($ pool)' cho tôi kết quả 101000100100 trong khi nếu tôi chỉ định 35, nó hoạt động 3UNPWR3GWHQP, và nếu tôi gán 36, nó đi kèm với bù trừ đơn vị – Zyoo

+0

@yolapop bạn hoàn toàn chính xác. Tôi đã có ý định viết $ pool như một mảng nhưng bằng cách nào đó đã viết nó thành một chuỗi. Hãy xem xét nó một mảng và phương pháp luận hoạt động. – Fanis

11

Câu trả lời rất muộn cho câu hỏi đã được trả lời, nhưng đây là giải pháp của chúng tôi. Nó tạo ra một khóa với kích thước/chiều dài có thể cấu hình và hậu tố tùy chọn dựa trên IPv4 hợp lệ, Userid (hoặc bất kỳ số nguyên có ý nghĩa nào) hoặc chuỗi văn bản. Nó cũng tránh các ký tự mơ hồ (i, 1, l, 0, o, O) trong kết quả chuẩn.

Chúng tôi thêm Userid vào giấy phép và sau đó có thể chuyển đổi phần đó về số nguyên base10 và kiểm tra xem nó có hợp lệ với tài khoản người dùng đang sử dụng giấy phép hay không.

$license = generate_license(); 
// YF6G2-HJQEZ-8JZKY-8C8ZN 

$license = generate_license(123456); 
// ZJK82N-8GA5AR-ZSPQVX-2N9C 

$license = generate_license($_SERVER['REMOTE_ADDR']); 
// M9H7FP-996BNB-77Y9KW-ARUP4 

$license = generate_license('my text suffix'); 
// Q98K2F-THAZWG-HJ8R56-MY-TEXT-SUFFIX 

Chúng tôi kiểm tra tính duy nhất trong cơ sở dữ liệu khi tạo, nhưng khả năng trùng lặp gần như bằng không.

/** 
* Generate a License Key. 
* Optional Suffix can be an integer or valid IPv4, either of which is converted to Base36 equivalent 
* If Suffix is neither Numeric or IPv4, the string itself is appended 
* 
* @param string $suffix Append this to generated Key. 
* @return string 
*/ 
function generate_license($suffix = null) { 
    // Default tokens contain no "ambiguous" characters: 1,i,0,o 
    if(isset($suffix)){ 
     // Fewer segments if appending suffix 
     $num_segments = 3; 
     $segment_chars = 6; 
    }else{ 
     $num_segments = 4; 
     $segment_chars = 5; 
    } 
    $tokens = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'; 
    $license_string = ''; 
    // Build Default License String 
    for ($i = 0; $i < $num_segments; $i++) { 
     $segment = ''; 
     for ($j = 0; $j < $segment_chars; $j++) { 
      $segment .= $tokens[rand(0, strlen($tokens)-1)]; 
     } 
     $license_string .= $segment; 
     if ($i < ($num_segments - 1)) { 
      $license_string .= '-'; 
     } 
    } 
    // If provided, convert Suffix 
    if(isset($suffix)){ 
     if(is_numeric($suffix)) { // Userid provided 
      $license_string .= '-'.strtoupper(base_convert($suffix,10,36)); 
     }else{ 
      $long = sprintf("%u\n", ip2long($suffix),true); 
      if($suffix === long2ip($long)) { 
       $license_string .= '-'.strtoupper(base_convert($long,10,36)); 
      }else{ 
       $license_string .= '-'.strtoupper(str_ireplace(' ','-',$suffix)); 
      } 
     } 
    } 
    return $license_string; 
} 
2

Giải pháp của tôi

implode('-', str_split(substr(strtoupper(md5(time() . rand(1000, 9999))), 0, 20), 4)); 
+0

Điều này rất thanh lịch! –

+0

Tốt! cho Serial bạn có thể giải mã trở lại ngày? –

Các vấn đề liên quan