Guida Creare Sistema licenze RSA per il tuo software (Offline + Online)

JunkCoder

Moderatore
5 Giugno 2020
1,682
25
1,492
603
[TITOLO]Sistema Licenze RSA Opensource in C#[/TITOLO]​

Introduzione

Rilascio su inforge un piccolo sistema di licenze in C# (scritto da me oggi) che sfrutta RSA-4096 e SHA-256 per firmare e validare il file di licenza. E' anche previsto che tale file possa essere trasmesso da un server remoto (un piccolo esempio in PHP e' incluso nel pacchetto). Allo stato attuale, senza un computer quantistico molto potente, non e' possibile generare un file di licenza valido senza possedere la chiave privata. Questo non rendera' il vostro programma inviolabile, pero' l'unico modo possibile per crackarlo restera' reversare e patchare l'eseguibile, cosa che potete ostacolare con ulteriori protezioni.

gui_sample.png


Contenuto
  • RSALicense- progetto C#
    • Form1 - Form principale
      • Bottone acquista - apre nel browser la pagina per l'acquisto (include l'HWID del pc in uso)
      • Bottone verifica online - Richiede al server remoto il file di licenza collegato all'HWID del pc in uso, se esiste
      • Bottone verifica offline - Stessa cosa ma il file e' sul vostro PC
      • Link Admin debug - Apre il form di test per generare una nuova licenza (non va pubblicato)
    • HWIDProvider
      • GetBinaryHWID - Esempio Hardware ID per prova (non usate questo in produzione)
      • GetClientID - Formatta l'HWID in formato testuale leggibile
    • LicenseManager
      • SignRSA - Funzione per firmare con la chiave privata
      • VerifyRSA - Funzione per verificare la firma, usando la chiave pubblica
      • Verify - Prende una licenza in formato testo e ne determina la validita'
      • PinnedKeyModulus + PinnedKeyExponent - Le componenti della chiave pubblica
    • sample_key.pem - La chiave privata RSA di esempio utilizzata per le prove
    • AdminForm - Form di amministrazione per generare licenze, NON VA PUBBLICATO
      • Button_click - Genera licenza valida per l'ID inserito
      • PrivateKey* - Le componenti della chiave privata RSA
  • Sample_Server- esempio server PHP
    • acquista.php
    • verifica.php
File di Licenza

Da cosa sara' composto il file di licenza? Da 2 semplici componenti:
  • L'ID del computer per cui e' valida la licenza
  • La firma dell'ID usando la chiave privata
A questo punto si uniscono le due componenti, mettendo prima la lunghezza della stringa ID, la lunghezza della firma, la stringa ID e infine la firma. Per contenere le lunghezze ho scelto di usare degli ushort (UInt16):

dump_licenza.png


In verde abbiamo la lunghezza dell'ID, che equivale a 39 caratteri.
In azzurro la lunghezza della firma, che e' 512 byte e ovviamente e' stata troncata nell'immagine.
Tra le "quadre" (di paint) in viola c'e' la stringa che rappresenta l'HWID (potete vederla a destra 2532-...-D779)
Mettere le lunghezze non era obbligatorio visto che sia l'HWID che la firma hanno sempre stessa dimensione ma le ho messe cosi' che voi possiate modificare il formato o aggiungere altri campi ad esempio Nome, email, data scadenza ecc.

Tutto questo viene convertito in base64 cosi' da avere un testo leggibile senza caratteri speciali e facile da copiare/incollare.

Verifica Online

E' una normale richiesta http, specificando l'HWID della macchina in uso. Se il server ha nel database una licenza attiva corrispondente a quell'HWID, la da' come risposta per intero. Anche se ci fosse un Man-In-The-Middle non potrebbe rubare la licenza per usarla (avendo un HWID diverso) ed anche alterando la risposta al massimo puo' far fallire la verifica. Consiglio comunque di usare SSL, specificando il vostro sito https, anche perche' se proponete l'acquisto, li' si che servira'.

HardwareID

Nonostante l'abbia gia' detto ci tengo a ripetere che il metodo usato e' di prova e da' una sicurezza solo apparente.
Questa guida/release e' incentrata su RSA, per cui non ho ritenuto opportuno riempirla di codice per ottenere l'indirizzo MAC della scheda di rete, il numero di serie dell'harddisk o altri metodi piu' sicuri. Il MachineGuid usato viene generato casualmente all'installazione di Windows, pero' puo' essere modificato senza problemi dall'utente, magari per farlo coincidere con quello di un PC che ha acquistato la licenza regolarmente, cosi' da avere lo sconto del 50%.

Generazione Licenze

Per mostrare il funzionamento ho inserito tutto in AdminForm.cs, anche la chiave privata, da non pubblicare.
Potete spostare questa parte di codice in un nuovo progetto, mettendolo ad esempio nel server per non doverle generare a mano quando qualcuno acquista. Oppure potreste farlo direttamente da PHP, che e' perfettamente in grado di firmare usando RSA.

Conclusione

Potete usare questo codice come vi pare, consiglio prima di sostituire la chiave di prova. Generate una vostra chiave RSA a 4096 bit e mettete solo e (esponente pubblico) ed m (modulo) embedded nell'eseguibile (LicenseManager.cs).

Download
 
salve, premetto che sono alle "prime armi" con la programmazione in C# e provo a porre una domanda, sperando che non sia troppo elementare: è possibile gestire il file di licenze introducendo una data di scadenza della licenza stessa? Grazie
 
salve, premetto che sono alle "prime armi" con la programmazione in C# e provo a porre una domanda, sperando che non sia troppo elementare: è possibile gestire il file di licenze introducendo una data di scadenza della licenza stessa? Grazie

Si, è possibile aggiungere un periodo di validità. Il problema di questo approccio è che fidandosi dell’orologio del computer è possibile spostarlo indietro per aggirare il controllo. L’unico modo per essere sicuri al 100% è che l’orario attuale deve essere verificato da un server e richiede quindi una connessione ad internet sempre presente.
 
  • Mi piace
Reazioni: vibraleg
Si, è possibile aggiungere un periodo di validità. Il problema di questo approccio è che fidandosi dell’orologio del computer è possibile spostarlo indietro per aggirare il controllo. L’unico modo per essere sicuri al 100% è che l’orario attuale deve essere verificato da un server e richiede quindi una connessione ad internet sempre presente.
grazie per la sollecita risposta...