|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Jun 2006
Messaggi: 117
|
[C#] Protezione della licenza
Salve,
nel software che sto sviluppando vorrei poter inserire una data di scadenza della licenza d'uso. Preciso subuto che il software e' un gestionale aziendale, quindi non esiste il pericolo che l'utente possa cambiare la data di sistema per fregarmi. Mi sono venute in mente varie idee pero' alla fine il problema ricade sempre su un fatto: la data di scadenza deve essere memorizzata da qualche parte, e quindi un utente smaliziato (se non smanettone) potrebbe trovarla e modificarla a piacimento. Nella mia testolina ho pensato ad alcuni scenari/soluzioni: 1) il file (poniamo anche un semplice xml) in cui e' contenuta la data di scadenza potrebbe essere criptato con una chiave simmetrica (AES o DES). All'avvio l'applicazione dovrebbe essere in grado di decriptare il file, ottenendo la data di scadenza in chiaro, confrontarla con quella di sistema ed eventualmente bloccare l'esecuzione se la licenza e' scaduta. Il problema e' che il software deve mantenere memorizzata la chiave simmetrica per decriptare la data di scadenza. Dunque il problema si sposta su "come memorizzare in maniera sicura la chiave simmetrica". Un cane che si morde la coda. 2) la data di scadenza potrebbe essere processata da una funzione hash sicura (SHA1 o MD5) e quindi sul file di licenza avrei un "digest" della data di scadenza reale, cioe' una stringa senza alcun senso e dalla quale l'utente smanettone non potrebbe ricavare alcuna informazione. Tuttavia gli algoritmi hash non sono poi cosi' tanti e quindi basterebbe fare alcune prove per trovare quello giusto (quello utilizzato dal mio software), generare manualmente l'hash di una data di scadenza a piacimento e sostituirla nel file della licenza. C'e' anche un secondo problema in questo scenario. Mentre nel primo decriptando la data di scadenza otterrei effettivamente una data di confrontare con quella attuale di sistema, in questo caso, avendo a che fare con dei digest, non potrei eseguire un test di comparazione del tipo "maggiore o uguale", ma solo di uguaglianza. Cioe' dovrei effettuare l'hash della data odierna di sistema e confrontarlo con l'hash della data di scadenza memorizzata. Il confronto e' quindi una semplice uguaglianza e quando l'uguaglianza e' verificata (il giorno della scadenza della licenza) si dovrebbe attivare un flag che da quel momento in poi impedirebbe l'esecuzione del software... beh ma allora il problema e': dove memorizzo in maniera sicura questo flag? Ancora il cane che si morde la coda!!! Qualcuno ha esperienza in merito? Consigli? Aiuti? Elemosina? Grazie mille Ultima modifica di mcaisco : 15-04-2009 alle 10:25. |
![]() |
![]() |
![]() |
#2 |
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
|
visto che fai l'assunzione molto forte e molto comoda che l'utente non possa cambiare la data di sistema allora leggi quella e fai un confronto con una data hard-coded.
|
![]() |
![]() |
![]() |
#3 | |
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
|
Quote:
![]() |
|
![]() |
![]() |
![]() |
#4 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
Puoi ad esempio creare un file ( che può essere il risultato della serializzazione di una classe... ) che contiene la data di scadenza criptata. Le chiavi di creazione/lettura delle stringhe criptate le lasci hard-coded nel codice, non c'è motivo di registrarle da altre parti. Ovviamente se l'utente modifica un solo carattere del file serializzato, lo corrompe o lo elimina, questo produce errori in fase di lettura e/o decriptazione dei valori criptati, all'apertura dell'applicazione. Errori che puoi intercettare ( Try Catch ) e nella cui gestione, chiudere in faccia l'applicazione allo smanettone di turno... E' chiaro che chiunque manometta quel file dovrà per forza rivolgersi a te, per far ripartire l'applicazione. Non so se era la tecnica a cui avevi già pensato. Con me ha funzionato... ![]() Tutto ciò ovviamente se il tuo scopo è creare "files-licenza" esterni e indipendenti dall'exe, che puoi ad esempio ridistribuire successivamente come "estensioni del periodo di prova" ecc... Se invece vuoi il controllo data più semplice in assoluto, sono d'accordo con la soluzione citata da 71104. |
|
![]() |
![]() |
![]() |
#5 |
Member
Iscritto dal: Jun 2006
Messaggi: 117
|
Mmm, ma scusate una cosa, non e' una pratica "erronea" inserire password e dati sensibili in maniera hard-coded?
In questo caso in pratica si tratta di inserire una data di scadenza hard-coded, ma in un certo senso, dovendo regolare l'esecuziona autorizzata del programma, va vista come se fosse una password. Non c'e' il rischio che l'utente smanettone possa facilmente decompilare l'eseguibile, trovare la data di scadenza, modificarla a piacimento e ricompilare il tutto a casa sua? Del resto si tratta di C#, cioe' codice interpretato, quindi quando compra il prodotto riceve degli eseguibili che sono compilati in un codice intermedio (IL mi pare si chiami). Sbaglio? |
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Se l'utente è smanettone al punto da decompilare/ricompilare e conosce pure il C#, beh, a sto punto non c'è password che tenga, ti elimina le tue routine di controllo licenza e buonanotte...
Se sei su questi livelli : 1. Alza il prezzo e distribuisci senza limitazioni e/o fornisci i sorgenti... 2. Usa DotFuscator o cerca un Sw serio ( roba che di solito è a pagamento ) di offuscamento del sorgente. Se scegli la 2. e riesci a trovare un buon tool freeware, fammelo sapere. ![]() |
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Se l'utente e' smanettone e non inserisci una risorsa esterna (macchina remota certificatrice) puoi fare quello che vuoi, puoi pensare quello che vuoi, ma il sistema potra' essere rotto.
E l'esistenza di una risorsa esterna e' comunque condizione necessaria, ma non sufficiente per la robustezza. Puo' diventare sufficiente (abbastanza sufficiente, diciamo 6--) quando parti di elaborazione sono remote, e che quindi il programma locale non sia tutto cio' che serve per funzionare. Delegando ad un server remoto sia l'autenticazione che l'esecuzione di qualcosa, poiche' il server remoto si "suppone" inviolabile (da qui il 6--) anche a fronte di smanettoni, allora lo smanettone a casa sua non ha modo di bypassare i limiti imposti dalle licenze.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
![]() |
![]() |
![]() |
#8 | |
Member
Iscritto dal: Jun 2006
Messaggi: 117
|
Quote:
Ho improntato il discorso in maniera un po' piu' ampia in effetti, in modo che magari potesse tornare utile anche ad altri utenti. Dunque la tua idea MarcoGG sarebbe quella di creare una classe serializzabile ad-hoc per gestire la licenza (magari meglio una dll separata). Questa classe quindi, nei metodi di serializzazione/deserializzazione deve utilizzare una chiave di criptazione hard-coded, accettando il rischio che decompilando il codice l'utente possa scoprire questa chiave. Accettato questo rischio mi viene in mente un unico problema: se ho N clienti, dovro' ricompilare la classe/dll per la gestione delle licenze N volte, perche' per ciascuna devo creare una nuova chiave. |
|
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
In questo caso sarà una semplice Public Class di cui esiste sempre e solo un'istanza, creata all'avvio dell'Applicazione... Poi avrai una classe, chiamiamola "ClassCriptatore", che avrà essenzialmente 2 metodi : Cripta / DeCripta... Se ad esempio usi DESCryptoServiceProvider, avrai bisogno di definire le 2 chiavi "Key" e "IV". Bene, queste 2 chiavi saranno hard-coded nella classe Criptatore, ovviamente NON nel file licenza, che invece è la serializzazione della classe ClassLicenza. Questa cosa della serializzazione te l'ho buttata lì così, perchè ti ho riportato un esempio di qualcosa che ho realizzato io ( nel mio caso c'erano diversi valori criptati da mettere nello stesso file licenza, per quello ho preferito farmi una classe e serializzarla ). Ovvio che se il tuo file licenza ha solo 1 valore, la data di scadenza, puoi metterla in un .txt qualunque, senza serializzare nulla e finita lì, ma il valore contenuto sarà cmq criptato. Se distribuisci N Client, avranno tutti le stesse chiavi di Criptazione, ma potranno avere date di scadenza diverse, senza bisogno di compilarli N volte. |
|
![]() |
![]() |
![]() |
#10 | |
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Quote:
Anzi con reflector puoi pure tranquillamente inserire codice all'interno di un assembly senza troppi problemi. |
|
![]() |
![]() |
![]() |
#11 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
Ovvio che, come giustamente segnalato da gugoXX, ci sono livelli di sicurezza ben superiori, ma che guarda caso richiederanno assai spesso tempi e costi superiori... La mia è una soluzione che si implementa abbastanza facilmente, e non ho mai conosciuto una segretaria o un ragioniere capace di bucarla... ![]() |
|
![]() |
![]() |
![]() |
#12 | |
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Quote:
O la data di scadenza è hard coded e quindi devi ricompilare il progetto per allungare la scadenza, oppure generi la data a partire dall'installazione (tipo 60 giorni da essa). Se lo generi dall'installazione però hai il problema che ad ogni installazione la data viene resettata rendendo di fatto inutile il controllo. Dovresti "marcare" la macchina alla prima installazione così che eventuali successive installazioni riconoscano che il software è già stato installato, come fanno molti applicativi che vanno a scrivere qualche file in qualche cartella o chiave di registro sperduta. |
|
![]() |
![]() |
![]() |
#13 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
La data di scadenza è in una stringa criptata nel File Licenza. 1. Ho una piccola Applicazione separata ( che ovviamente non distribuirò al cliente ![]() 2. Nell'Applicazione leggo la data dal File Licenza, se la lettura/decriptazione va a buon fine, la data letta è valida, e passo al controllo con la data di sistema ( e in questo caso, come dichiarato, si è certi che l'utente non ha modo di modificarla da Bios o da S.O. ... ). 3. Qualsiasi errore di lettura/decriptazione dal File Licenza viene intercettato e produce il blocco dell'Applicazione. 4. L'eventuale Installer NON genera alcun File Licenza, che invece distribuisco separatamente... ![]() |
|
![]() |
![]() |
![]() |
#14 |
Senior Member
Iscritto dal: Jun 2007
Messaggi: 1232
|
Usare una chiavetta Hardware?
__________________
Cpu: Amd 64 X2 5200+ - Mobo:M2N32SLI DELUXE - Ram: Corsair xms2 800 mhz kit 4gb - SK Video: Gaiward GTS250 - Ali : Enermax Liberty 500 Wat - Mast DVD: 2 Nec AD-5170A - Case : Thermaltake Armor+ - Dissipatore: Thermaltake V1 Notebook: Sony Vaio VGN-Fe21M-Pda: Htc Diamond |Il mio sito|Flickr| Stanco del solito forum? Vieni a parlare di fotografia su Fotoni |
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Con associato costo e inoltre costringere l'utente a tenere occupata una porta usb per usare un'applicativo gestionale? (Tenendo conto appunto della situazione contingente, cioè che l'utente medio non sa manco dove mettere le mani per trovare il file di licenza, figurarsi a decrittarlo...)
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
![]() |
![]() |
![]() |
#16 |
Member
Iscritto dal: Jun 2006
Messaggi: 117
|
Beh in effetti il mio pensiero attualmente ricalca quello di MarcoGG. Si tratta di un sistema di sicurezza certamente naif, inadatto nel caso in cui l'utente possa essere anche un programmatore esperto, ma in questo caso non c'e' questo pericolo.
E' ovvio che una soluzione simile implica la previa generazione del file di licenza da parte del vendor (cioe' io in questo caso) con la data di scadenza desiderata... ovviamente con il massimo automatismo possibile. L'unica pecca rimane se c'e' la necessita' di generare non solo date di scadenza diverse, ma si voglia anche utilizzare una chiave di cifratura per tale data diversa per ogni utente. Essendo tale chiave necessariamente hard-coded in questo scenario, occorre ricompilare tutto ogni volta che si distribuisce un nuovo file di licenza. Per questo motivo attualmente pensavo di utilizzare una dll esterna che svolga il compito di controllare la licenza decrifrando il file in cui e' serializzata/memorizzata. In questo modo ogni volta devo solo ricompilare la dll con la nuova chiave di cifratura hard-coded, generare il file di licenza con la data criptata con la nuova chiave, e distribuire al cliente entrambi gli elementi (dll e file). No? Sulle chiavi hardware sono d'accordo con banryu79... costosissime tanto che sono utilizzate solo da sistemi software proprietari molto complessi e costosi gia' di per se'. |
![]() |
![]() |
![]() |
#17 | |
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Quote:
![]()
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
![]() |
![]() |
![]() |
#18 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
![]() Occhio poi a non fare casino con Applicazioni / DLL-Chiavi / Files-Licenza ! ![]() |
|
![]() |
![]() |
![]() |
#19 |
Member
Iscritto dal: Jul 2008
Messaggi: 237
|
Non vorrei rovinare la giornata a nessuno, ma consiglio fortemente di considerare i seguenti punti:
Inutile affidarsi a soluzioni quali SmartAssembly, .NET Reactor o peggio ancora DotFuscator perché esistono unpackers in grado di rimuovere la maggior parte dell'offuscamento e di ridurre di fatto gli effetti negativi alla sola perdita di certi metadati. Infine non ha senso affidarsi al noto Themida/WinLicense per i prodotti .NET poiché i prodotti di casa oreans non alterano minimamente il codice CIL né sono efficaci ad impedirne il dump in runtime. |
![]() |
![]() |
![]() |
#20 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
![]() Ho consigliato anch'io l'offuscamento. DotFuscator l'ho nominato perchè già "impacchettato" in .Net, ma sinceramente non è che mi abbia proprio esaltato. Interessante cmq il tuo intervento. ![]() Vorrei sapere se conosci anche dotNet Protector di PV Logiciels, se l'hai provato e che giudizio ne dai. |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 23:51.