Chiave di licenza / generatore e controllore del numero di serie

16

Ho bisogno di un generatore di numeri di serie e di un correttore di accompagnamento. Mi piacerebbe essere in grado di impostare un sale (e forse una lunghezza). Il generatore dovrebbe produrre solo numeri seriali che superino il test del controllore. Questi numeri dovrebbero rappresentare solo una piccola parte di tutti i possibili numeri della lunghezza specificata.

L'algoritmo non deve essere crittograficamente sicuro . Piuttosto, dovrebbe essere molto facile da implementare (in javascript) e dovrebbe essere molto veloce.

Per chiarire: se acquisti software commerciale, a volte è protetto con un numero di serie / una chiave. Se lo digiti, il software lo verifica in modo algoritmico (controllando se soddisfa determinate proprietà), piuttosto che cercare un enorme database. Sono anche abbastanza sicuro che le chiavi fossero tutte generate algoritmicamente piuttosto che a mano. E solo una piccola parte di tutte le possibili chiavi di una determinata lunghezza sono effettivamente valide, quindi è difficile indovinare le chiavi.

Salt: Non so se salt è la parola giusta, ma l'algoritmo dovrebbe avere almeno un parametro, la cui scelta altera le chiavi generate (in modo che più persone possano usare lo stesso algoritmo e non debbano temere collisioni) .

    
posta Dave 07.03.2011 - 03:37
fonte

3 risposte

26

Se non c'è un reale bisogno di sicurezza, ecco un generatore di numeri seriali molto veloce, con un correttore:

  • Utente un contatore. Inizializza a 0. Quando vuoi un nuovo numero di serie, incrementa il contatore di 1000; il nuovo valore del contatore è il numero di serie. Il correttore funziona così: un numero di serie è valido se termina con tre zeri. Solo un numero su 1000 sarà accettato dal controllore.

Se questa soluzione non ti soddisfa, allora fai hai bisogno di sicurezza, e questo richiede la crittografia.

La soluzione crittograficamente sicura deve avere i numeri seriali firmati: il numero di serie è la codifica di alcuni payload (ad esempio un contatore di tutti i numeri seriali che hai generato) e una firma sul payload. Il generatore ha una chiave privata, che usa per calcolare le firme; il controllore conosce solo la chiave pubblica corrispondente. Il problema con questa configurazione non riguarda in realtà il tempo di verifica, anche in Javascript; piuttosto, è la taglia della firma che è un problema. Suppongo che il numero seriale sarà, a un certo punto, digitato da un utente. La dimensione minima teorica per una firma crittograficamente sicura è di circa 80 bit (poiché le firme possono essere verificate solo con la chiave pubblica, un utente malintenzionato potrebbe provare tutte le possibili sequenze di bit e di solito richiediamo un livello di sicurezza di almeno 2 80 ). Tuttavia, le firme più piccole tra gli "schemi di sicurezza presunti" sono più vicine a 160 bit (con BLS , che utilizza un accoppiamento, che è un po 'complesso da implementare) o 320 bit (con DSA o ECDSA ). C'è un po 'di lavoro sui sistemi di firma con firme più brevi ( Quartz , o McEliece-Niederreiter ) ma c'è parecchia polemica sulla loro sicurezza.

Anche con lettere maiuscole e cifre (36 possibili caratteri, e ci sono sia "I" che "1", e anche "O" e "0"), una firma a 160 bit utilizzerà 31 caratteri. Insieme al payload, si otterranno numeri seriali di lunghezza pari o superiore a 35, che è probabilmente troppo per un utente medio da digitare (ma non con un ampio margine, una firma a 80 bit si adatterebbe bene). p>

Se non usi uno schema di firma, allora devi essere consapevole che un aggressore ragionevolmente determinato sarà in grado, attraverso un certo disassemblaggio, di eludere il controllore, o anche di imparare abbastanza per essere in grado per produrre i propri numeri di serie (che il correttore accetterà volentieri). A quel punto, non otterrete una sicurezza quantificata: non sarete in grado di dire: "il mio piano è sicuro fino a un budget di 3,8 miliardi di dollari". Piuttosto, andrà come: "il mio schema è sicuro fino a quando uno studente abbastanza spiritoso e annoiato arriva, inverte il codice di controllo e pubblica il risultato su Facebook".

Il classico schema non proprio sicuro sarebbe simile a questo:

  • Usa il contatore dello schema precedente (quello con le estremità con tre zeri). Codificalo come un blocco a 64 bit. Criptare quel blocco con una chiave simmetrica con hardcoded, usando un codice a blocchi. Il correttore conosce la chiave e verifica il numero di serie decodificandolo (con la stessa chiave simmetrica codificata) e osservando gli zeri finali.

Questo non è più sicuro del normale contatore, ma almeno i numeri seriali saranno casuali. Con un alfabeto di 34 caratteri (cifre e lettere maiuscole eccetto "O" e "I"), un blocco a 64 bit richiede 13 lettere, che è probabilmente accettabile (un tipico numero seriale Microsoft ha 25 lettere). Per la cifratura a 64 bit, raccomando XTEA , che dovrebbe essere abbastanza veloce e semplice da implementare.

    
risposta data 07.03.2011 - 15:02
fonte
6

Se si desidera il metodo crittograficamente sicuro non si ottiene una connessione Internet per verificare la serie. Ciò significa che un tale schema di protezione è più adatto per il software basato su abbonamento rispetto a quello per il software di scaffale tradizionale.

Con le connessioni Internet è semplice (dato che usi JS, presumo che sia quello che vuoi):

  1. Qualcuno crea una chiave, quella parte deve conoscere il segreto
  2. Il server conosce il segreto ed è in grado di decodificare i dati
  3. Il client invia la chiave, che è un blob binario codificato in Base32 (vedi anche this )
  4. Il server decrittografa la chiave e controlla se è valida (sia sintatticamente che semanticamente)

Senza connessione a Internet è ancora possibile utilizzare uno schema simile alla firma PGP per verificare che il blob che l'utente inserisce sia stato creato da te. La crittografia non funzionerà allo stesso modo, poiché la decrittazione richiede sempre di conoscere il segreto e il grosso problema qui è:

  1. non ti fidi dell'utente (altrimenti non avresti bisogno dello schema di protezione)
  2. dai all'utente il segreto, compilato nel tuo file binario

Ovviamente entrambi i punti si contraddicono a vicenda. Da una parte non ti fidi dell'utilizzatore, dall'altra devi distribuire il segreto usato per la decrittazione.

Tutto sommato devo concludere che senza la connessione Internet e il controllo di validità basato sul server che risulta nella rivelazione di alcune conoscenze (ad es. il contenuto che è utile solo per così tanto tempo) qualsiasi schema di protezione che ho visto finora è più o meno una corsa agli armamenti tra cracker e venditori.

Ora, se non è importante avere un sistema crittograficamente sicuro, farei comunque qualsiasi dato binario che tu possa proteggere con un semplice CRC o altro. Ciò che viene in mente sarebbe:

  1. Avere un numero di serie monotonicamente crescente
  2. XOR con il tuo valore di sale (o qualsiasi altra operazione reversibile)
  3. Prendi il CRC32 di quel valore (o Adler32 o qualsiasi altra cosa) - aggiungi più sale qui se necessario
  4. Codifica con Base32 (facilita la leggibilità, ecc.)
  5. Controlla solo che CRC32 abbia validità ...
risposta data 07.03.2011 - 15:49
fonte
3

OP ha scritto "dovrebbe essere molto facile da implementare (in javascript) e dovrebbe essere molto veloce"

Non è chiaro se "in javascript" si riferisce al generatore o al controllore oa entrambi, o se si riferisce a "javascript nel browser" o ad altre implementazioni java / ecmascript (ad esempio lato server nel server Web) .

Javascript come linguaggio di implementazione non è necessariamente un problema, e ci sono un paio di librerie crittografiche per javascript (che supportano MD5, DES, AES, SHA, PBKDF2, HMAC):

La velocità non dovrebbe essere un problema troppo grande (i motori javascript del browser sono abbastanza utilizzabili da questo punto di vista, una volta superato IE6 / 7).

Tuttavia, nessuno dei due precedenti supporta la crittografia della chiave pubblica (che è richiesta per la sicurezza se il "correttore" è distribuito all'utente non fidato e quindi non può essere consentito l'accesso alla chiave utilizzata per creare numeri seriali) - per non parlare dello specifico algoritmi suggeriti da Thomas, sopra. Google presenta alcuni hit per implementazioni a chiave pubblica in JavaScript (http://www-cs-students.stanford.edu/~tjw/jsbn/, link , link ) ma personalmente sarei ancora più nervoso per il loro bug- free-ness rispetto alle librerie "più grandi" sopra.

Forse in modo più significativo, anche con un approccio basato su una chiave pubblica, se il generatore o il correttore sono distribuiti all'utente non fidato, lo schema non è sicuro. Se il codice generatore è disponibile per l'utente non fidato, è possibile generare tutte le chiavi che preferiscono, mentre se il correttore è disponibile per l'utente non fidato, può semplicemente modificare il codice javascript per saltare i controlli. [Lo stesso problema si pone con il codice nativo, ovviamente, ma, anche con l'offuscamento, JavaScript è probabilmente più semplice da attaccare attraverso le modifiche locali.]

Prima di implementare uno schema di sicurezza in JavaScript dovresti considerare anche i problemi di trust più ampi: vedi link per un sommario utile.

    
risposta data 27.11.2011 - 13:35
fonte