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.
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
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. " –
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. –