2010-03-30 15 views
5

è tardi, sono stanco, e, probabilmente, essendo abbastanza denso ....Garantire una chiave di licenza con chiave RSA

Ho scritto un programma che ho bisogno di fissare in modo che verrà eseguito solo su macchine che ho generare una chiave per. Quello che sto facendo per ora è ottenere il numero seriale del BIOS e generare un hash da quello, quindi lo sto crittografando usando una chiave privata XML RSA. Quindi firmo l'XML per assicurarmi che non venga manomesso. Sto cercando di impacchettare la chiave pubblica per decifrare e verificare la firma, ma ogni volta che provo a eseguire il codice come utente diverso da quello che ha generato la firma ottengo un errore nella firma.

Gran parte del mio codice è stato modificato dal codice di esempio che ho trovato poiché non mi è familiare con la crittografia RSA come vorrei. Di seguito è riportato il codice che stavo usando e il codice che pensavo di aver bisogno di usare ...

Qualsiasi feedback sarebbe molto apprezzato in quanto sono abbastanza perso a questo punto il codice originale con cui stavo lavorando era questo, questo codice funziona bene fino a quando l'utente lancio del programma è lo stesso che ha firmato il documento originariamente ...

CspParameters cspParams = new CspParameters(); 
      cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"; 
      cspParams.Flags = CspProviderFlags.UseMachineKeyStore; 

      // Create a new RSA signing key and save it in the container. 
      RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams) 
      { 
       PersistKeyInCsp = true, 
      }; 

questo codice è quello che io credo che dovrei fare ma è non riuscire a verificare il firma indipendentemente da ciò che faccio, indipendentemente dal fatto che si tratti dello stesso utente o di uno diverso ...

RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(); 
      //Load the private key from xml file 
      XmlDocument xmlPrivateKey = new XmlDocument(); 
      xmlPrivateKey.Load("KeyPriv.xml"); 
      rsaKey.FromXmlString(xmlPrivateKey.InnerXml); 

Credo che questo abbia qualcosa a che fare con il nome del contenitore chiave (Essendo un vero idiota qui per favore mi scusi) Sono abbastanza sicuro che questa sia la linea che sta facendo sì che funzioni nel primo caso e impedendole di lavorare nel secondo caso ....

cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"; 

esiste un modo per me di firmare/cifrare il XML con una chiave privata quando viene generato la licenza dell'applicazione e poi cadere la chiave pubblica nella directory di applicazione e l'uso quello per verificare/decifrare il codice? Posso eliminare la parte di crittografia se riesco a far funzionare correttamente la parte della firma. Lo stavo usando come backup per offuscare l'origine del codice di licenza da cui sto digitando.

Tutto ciò ha senso? Sono un somaro?

Grazie per qualsiasi aiuto qualcuno mi può dare in questo ..

risposta

5

Ho usato questo metodo per firmare documenti XML utilizzando una chiave privata memorizzata in un file XML che ho poi incorporato nel dll applicazione come una risorsa. Penso che potresti essere alle prese con i permessi di accesso al keystore e questo creerebbe anche problemi nel trasferire il codice ad altri server, ecc.

Ecco il codice per ottenere la chiave privata come risorsa incorporata e firmare il documento: (segno è il nome della classe questo metodo si trova in, Licensing.Private.Private.xml è una combinazione di spazio dei nomi di default + cartella + il nome del file della risorsa)

public static void SignDocument(XmlDocument xmldoc) 
{ 
    //Get the XML content from the embedded XML privatekey. 
    Stream s = null; 
    string xmlkey = string.Empty; 
    try 
    { 
     s = typeof(Sign).Assembly.GetManifestResourceStream("Licensing.Private.Private.xml"); 

     // Read-in the XML content. 
     StreamReader reader = new StreamReader(s); 
     xmlkey = reader.ReadToEnd(); 
     reader.Close(); 
    } 
    catch (Exception e) 
    { 
     throw new Exception("Error: could not import key:",e); 
    } 

    // Create an RSA crypto service provider from the embedded 
    // XML document resource (the private key). 
    RSACryptoServiceProvider csp = new RSACryptoServiceProvider(); 
    csp.FromXmlString(xmlkey); 
    //Creating the XML signing object. 
    SignedXml sxml = new SignedXml(xmldoc); 
    sxml.SigningKey = csp; 

    //Set the canonicalization method for the document. 
    sxml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigCanonicalizationUrl; // No comments. 

    //Create an empty reference (not enveloped) for the XPath transformation. 
    Reference r = new Reference(""); 

    //Create the XPath transform and add it to the reference list. 
    r.AddTransform(new XmlDsigEnvelopedSignatureTransform(false)); 

    //Add the reference to the SignedXml object. 
    sxml.AddReference(r); 

    //Compute the signature. 
    sxml.ComputeSignature(); 

    // Get the signature XML and add it to the document element. 
    XmlElement sig = sxml.GetXml(); 
    xmldoc.DocumentElement.AppendChild(sig); 
} 

Utilizzare il seguente codice genera il privato .xml e public.xml chiavi. Mantenere il file private.xml sicuro, ovviamente.

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); 
File.WriteAllText(@"C:\privateKey.xml", rsa.ToXmlString(true)); // Private Key 
File.WriteAllText(@"C:\publicKey.xml", rsa.ToXmlString(false)); // Public Key 
+0

Fantastico! Grazie per l'aiuto! Non solo ha risolto il mio problema di licenza, ma mi ha aiutato a gestire altre risorse nella mia app. –

+0

Ho appena notato che non mi sto sistemando lo StreamReader in un blocco di cattura alla fine ... –

0

Guess, il problema è che diversi utenti non hanno accesso alla chiave che viene memorizzata per il 1 ° utente (Si prega di notare: io non sono un esperto di crittografia).

Problemi correlati