2009-04-28 11 views
5

Dalla descrizione dell'utilità sn.exe e this question Vedo che una copia della chiave pubblica viene aggiunta a ogni assembly firmato con il nome sicuro. Questo è sufficiente per verificare che il binario dell'assieme non sia stato alterato.Devo pubblicare la chiave pubblica dal file .snk?

Ma come si può verificare che un determinato assieme sia stato effettivamente firmato con una determinata coppia di chiavi e compilato da una determinata azienda? Chiunque poteva generare la sua propria coppia di chiavi, produrre un assemblaggio e firmarlo con la sua coppia di chiavi. Devo pubblicare la chiave pubblica in modo che coloro che vogliono verificare l'origine dell'assembly possano confrontare le chiavi pubbliche? se sì, qual è il modo migliore per farlo?

risposta

5

No, non è necessario pubblicare la chiave pubblica al di fuori del gruppo dal momento che è hash e memorizzato come un segno accanto al riferimento all'interno dell'applicazione del cliente:

AssemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bcd6707151635d07" 

Questo dà un metodo per assicurare che tutte le future versioni dell'assembly siano compilate con la stessa coppia di chiavi e quindi dallo stesso editore.

Maggiori dettagli su come avere questa informazione impedisce a un'altra fonte di fingere di essere si può trovare nella mia altra risposta.

3

Ho sempre compreso lo scopo di firmare un assembly come controllo di runtime per garantire che gli aggiornamenti del codice provengano da una fonte attendibile. Effettivamente stanno cercando di evitare questo tipo di scenario:

Acquisto una libreria di crittografia dalla società A, poco dopo l'azienda B ottiene i miei dettagli e-mail e mi invia un aggiornamento gratuito all'assemblaggio che finge di essere un grosso bug di sicurezza correzione dalla società A quando in realtà introduce un metodo nascosto nel mio codice che invia tutti i dati che stavo cercando di crittografare ai server della società B. Supponendo che io sia un idiota e aggiungo ciecamente questa nuova dll nella directory bin della mia applicazione, il fatto che questo non sia stato firmato con la stessa chiave privata della vecchia versione verrà prelevato in fase di esecuzione causando un'eccezione e proteggendo i miei dati.

Quindi, non vedo alcun motivo per cui pubblicheresti la chiave pubblica al di fuori dell'assembly poiché non si suppone che garantisca che il file originale proviene da un fornitore specifico, solo che tutte le versioni successive provengono dallo stesso posto di il primo.

Wikipedia dice la stessa cosa (solo in un numero significativamente inferiore di parole).


A cura di aggiungere ulteriori informazioni, nel tentativo di rendere più chiaro ...

Penso che la cosa che deve essere chiarito prima è che le coppie di chiavi pubbliche e private sono unici. Ciò significa che conoscere la chiave pubblica non è abbastanza informazioni per ricostruire l'assemblea in modo che passi gli stessi controlli di hash.

Quindi Utente Z che sta utilizzando una libreria di crittografia dall'azienda A che si trova nella cartella bin delle applicazioni. Per fare questo ha fa riferimento la DLL come segue:

Encryption, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bcd6707151635d07" 

Lo scopo della chiave pubblica è quello di fornire a noi con three benefits che penso io, uno alla volta.

In primo luogo, fornisce un nome univoco per l'assembly - questo non ci dà ulteriore sicurezza ma blocca lo stile dll Hell dove due diverse società potrebbero rilasciare due librerie diverse chiamate Encyption versione 1.0.0.0 e non si sarebbe in grado per memorizzarli nella stessa directory poiché non c'è modo di differenziarli.

In secondo luogo, impedisce lo scenario che ho delineato nel mio post originale. È impossibile per la società B creare un'altra versione della libreria di crittografia che è anche la versione 1.0.0.0 e ha la stessa chiave pubblica (in modo che l'intero nome corrisponda e si chiamerebbe il proprio codice anziché quello della società A). Non possono farlo perché se la loro chiave pubblica corrisponde, allora anche la chiave privata deve corrispondere (poiché ogni coppia è unica). L'unico modo per ottenere la chiave privata da abbinare è compromettere la sicurezza della società A.

Infine garantisce l'integrità del file (modificato tramite corruzione o iniezione di codice dannoso). La DLL viene sottoposta a hashing in fase di esecuzione (quando è privata e nella cartella bin dell'applicazione) o durante l'installazione (quando viene inserita nel GAC) utilizzando la chiave pubblica e tale hash viene confrontato con l'hash che è stato encrpitato dal privato chiave e memorizzata nell'assieme. This page ha alcuni diagrammi e maggiori dettagli. Ancora una volta l'unico modo per simulare questo hash è conoscere la chiave privata.

Quindi, per coprire lo scenario specifico che ho descritto sopra, fingere che io sia Company B cercando di fornire all'utente Z una versione dannosa della dll di crittografia. Il mio primo tentativo è quello di creare semplicemente la mia dll con il nome Encryption e Versione 1.0.0.0 e firmarla con la mia coppia di chiavi. Sfortunatamente non posso cambiare il codice di riferimento nell'applicazione dell'Utente Z, quindi fallisce il controllo completo del nome e non viene caricato. "Okay," dico mentre faccio roteare i miei baffi, "cambierò semplicemente la chiave pubblica del mio assemblaggio in modo che corrisponda a quella dell'Azienda A". Una volta fatto questo, passa il controllo del nome, ma il controllo dell'hash fallirà perché l'app User Z non sarà in grado di decodificare l'hash memorizzato nell'assembly (che è stato crittografato con la chiave privata della Company B) con la chiave pubblica (Azienda A) che è stato fornito. Pertanto l'unico modo per la società B di creare una libreria che finge di essere la società A è conoscere la chiave privata della società A. Nessuno di questi controlli di sicurezza è dipendente dalla società A che pubblica la chiave pubblica da qualsiasi altra parte ma nella versione originale dell'assembly.

Si noti inoltre che tutte queste funzionalità non garantiscono (e non pretendono di garantire) che l'assemblaggio originale proviene dalla società A, che viene gestito da altri sistemi come il servizio Verisign o Microsoft Authenticode, ma garantiscono solo che una volta che hai fatto riferimento all'assieme, solo la società A può apportare modifiche a quel codice.

+0

Questo è assolutamente non chiaro e non menzionato esplicitamente nell'articolo collegato.Per fare tutto ciò, il runtime deve memorizzare nella cache gli hash di ogni singolo assembly e verificarlo durante il caricamento dell'assembly. Lo fa davvero? – sharptooth

+1

Secondo "CLR via C#" di Jeffery Richter, lo fa quando l'assembly non è nel GAC. Citando dal libro: "Quando gli assembly fortemente denominati vengono caricati da una posizione diversa da GAC, il CLR confronta i valori hash quando l'assembly viene caricato. In altre parole, un hash del file viene eseguito ogni volta che un'applicazione viene eseguita e carica l'assembly Questo colpo di prestazioni è un compromesso per essere certi che il contenuto del file di assembly non sia stato manomesso. " –

+0

Aggiungerò anche questa citazione da "C# tramite CLR" (libro altamente consigliato tra l'altro): "Importante: questo meccanismo garantisce solo che il contenuto di un file non sia stato manomesso. Il meccanismo non consente di indica chi è l'editore a meno che tu non sia assolutamente sicuro che l'editore abbia prodotto la chiave pubblica che hai e sei sicuro che la chiave privata del publisher non sia mai stata compromessa. " Pertanto, anche se pubblicano la chiave pubblica separatamente dall'assieme, non consente comunque di verificare l'editore. –

2
  1. È possibile rivolgersi a un fornitore di certificati di parti 3D (ad esempio VeriSign) e acquistare un certificato da loro (Code Signing At Verisign).
  2. Si utilizza un determinato certificato con il nome dell'azienda, l'URL, ecc. Su di esso per firmare il codice.
  3. Scarico l'app e guardo l'elenco di certificati con cui è stata firmata l'app.
  4. Uso il certificato, torna a VeriSign e verifica che il certificato sia stato effettivamente rilasciato a MyCompany, LLC.
  5. Osservo i certificati che sono stati utilizzati per emettere il certificato e verificare che VeriSign sia uno di questi (Windows viene fornito con pochi certificati attendibili installati).

Sommario:
Non solo verificare che il codice non è stato armeggiato con, ma anche è stato firmato con un certificato emesso da una festa di fiducia.

+1

Capisco tutto questo e questo è ciò che effettivamente facciamo. Ma questo non ha nulla a che fare con nomi forti e file .snk, non è vero? – sharptooth

+0

È passato un po 'di tempo da quando l'ho fatto. Ma IIRK usi la chiave pubblica del tuo certificato per firmare il tuo codice. Cioè .snk viene prodotto/esportato dal file .cer che si ottiene da VeriSign usando makecert.exe. Tale codice di firma in realtà fa due cose 1) impedisce al codice di essere armeggiato con (protezione) 2) autentica l'editore. –

Problemi correlati