Strategia per mantenere informazioni segrete come le chiavi API fuori dal controllo del codice sorgente?

209

Sto lavorando su un sito Web che consentirà agli utenti di accedere utilizzando le credenziali OAuth da utenti come Twitter, Google, ecc. Per fare ciò, devo registrarmi con questi vari provider e ottenere una chiave API super-segreta che devo proteggere con pegni contro varie parti del corpo. Se la mia chiave viene cancellata, la parte viene strappata.

La chiave API deve viaggiare con la mia fonte, poiché viene utilizzata in fase di esecuzione per eseguire richieste di autenticazione. Nel mio caso, la chiave deve esistere all'interno dell'applicazione in un file di configurazione o all'interno del codice stesso. Questo non è un problema quando costruisco e pubblico da una singola macchina. Tuttavia, quando inseriamo il controllo del codice sorgente nel mix, le cose diventano più complicate.

Dato che sono un bastardo a buon mercato, preferirei di gran lunga utilizzare servizi di controllo del codice sorgente gratuiti come TFS nel cloud o GitHub. Questo mi lascia un piccolo enigma:

Come posso mantenere intatto il mio corpo quando le mie chiavi API sono nel mio codice e il mio codice è disponibile in un repository pubblico?

Posso pensare a un certo numero di modi per gestirlo, ma nessuno di questi è soddisfacente.

  • Potrei rimuovere tutte le informazioni private dal codice e modificarlo di nuovo dopo la distribuzione. Questo sarebbe un grave problema da implementare (non illustrerò in dettaglio i molti modi), e non è un'opzione.
  • Potrei crittografarlo. Ma siccome devo decriptarlo, chiunque abbia la fonte potrebbe capire come farlo. Inutile.
  • Potrei pagare per il controllo del codice sorgente privato. LOL j / k spendere soldi? Per favore.
  • Potrei usare le funzionalità del linguaggio per separare le informazioni sensibili dal resto della mia fonte e quindi tenerle dal controllo del codice sorgente. Questo è quello che sto facendo ora, ma potrebbe essere facilmente rovinato controllando erroneamente il file segreto.

Sono davvero alla ricerca di un modo garantito per garantire che non condivido i miei dati personali con il mondo (eccetto su snapchat) che funzionerà senza intoppi attraverso lo sviluppo, il debugging e l'implementazione, oltre ad essere infallibile. Questo è completamente irrealistico. Quindi, cosa posso realisticamente fare?

Dettagli tecnici: VS2012, C # 4.5, il controllo del codice sorgente sarà il servizio TF o GitHub. Attualmente si utilizza una classe parziale per suddividere i tasti sensibili in un file .cs separato che non verrà aggiunto al controllo del codice sorgente. Penso che GitHub possa avere il vantaggio dato che .gitignore potrebbe essere usato per assicurare che il file di classe parziale non sia archiviato, ma l'ho già rovinato prima. Sto sperando in un "oh, problema comune, questo è come lo fai" ma potrei dover accontentarmi di "che non fa schifo quanto potrebbe",: /

    
posta Will 21.07.2013 - 22:18
fonte

12 risposte

124

Non inserire le tue informazioni segrete nel tuo codice. Inseriscilo in un file di configurazione che viene letto dal tuo codice all'avvio. I file di configurazione non dovrebbero essere messi sul controllo di versione, a meno che non siano "predefiniti di fabbrica", e quindi non dovrebbero avere alcuna informazione privata.

Vedi anche la domanda Controllo versione e file di configurazione personale per come farlo bene.

    
risposta data 21.07.2013 - 22:43
fonte
28

Potresti inserire tutte le chiavi private / protette come variabili di ambiente di sistema. Il tuo file di configurazione sarà simile a questo:

private.key=#{systemEnvironment['PRIVATE_KEY']}

Ecco come gestiamo questi casi e nulla entra nel codice. Funziona molto bene combinato con diversi file e profili di proprietà. Utilizziamo diversi file di proprietà per diversi ambienti. Nel nostro ambiente di sviluppo locale inseriamo le chiavi di sviluppo nei file delle proprietà per semplificare la configurazione locale:

private.key=A_DEVELOPMENT_LONG_KEY
    
risposta data 22.07.2013 - 13:40
fonte
27

Pure Git way

  • .gitignore file incluso con dati privati
  • Utilizza un ramo locale, in cui sostituisci TEMPLATE con DATA
  • Utilizza filtri sfumati / puliti, in cui lo script del filtro (locale) esegue la sostituzione bidirezionale TEMPLATE < - > %codice%

Modo mercuriale

  • MQ-patch (es) in cima al codice fittizio, che sostituisce DATA con TEMPLATE (i changeset sono pubblici, la patch è privata)
  • Estensione di parole chiave con parole chiave appositamente progettate (espanse solo in la tua directory di lavoro )

Modo agnostico SCM

  • avere la sostituzione delle parole chiave come parte del processo di creazione / distribuzione
risposta data 21.07.2013 - 23:29
fonte
14

Questo è molto specifico per Android / Gradle, ma puoi definire le chiavi nel tuo file gradle.properties globale che si trova in user home/.gradle/ . Questo è anche utile in quanto è possibile utilizzare diverse proprietà a seconda di buildType o flavouring i.e API per dev e di diverso per release.

gradle.properties

MY_PRIVATE_API_KEY=12356abcefg

build.gradle

buildTypes {
        debug{
            buildConfigField("String", "GOOGLE_VERIFICATION_API_KEY", "\"" + MY_PRIVATE_API_KEY +"\"")
            minifyEnabled false
            applicationIdSuffix ".debug"
            }
        }

Nel codice si farebbe riferimento in questo modo

String myAPI = BuildConfig.GOOGLE_VERIFICATION_API_KEY;
    
risposta data 29.05.2015 - 20:40
fonte
13

Metto segreti in file crittografati che poi commetto. La frase di accesso viene fornita all'avvio del sistema oppure viene memorizzata in un file di piccole dimensioni che non eseguo il commit. È bello che Emacs gestisca con allegria questi file crittografati. Ad esempio, il file init di emacs include: (carica "secrets.el.gpg"), che funziona correttamente - richiedendomi la password per quelle rare occazioni quando avvio l'editor. Non mi preoccupo se qualcuno interrompe la crittografia.

    
risposta data 09.12.2013 - 06:16
fonte
11

Non supponete di distribuire quella chiave con la vostra applicazione o di memorizzarla nel repository del codice sorgente. Questa domanda ti chiede come farlo, e questo non è ciò che viene normalmente fatto.

Applicazione Web mobile

Per Android / iPhone il dispositivo deve richiedere la chiave dal proprio servizio Web quando l'app viene eseguita per la prima volta. La chiave viene quindi memorizzata in un luogo sicuro. La chiave deve essere cambiata o revocata dal publisher. Il tuo servizio web può pubblicare una nuova chiave.

Applicazione Web ospitata

I clienti che utilizzano una licenza del software dovranno inserire manualmente la chiave quando configurerà il software per la prima volta. Puoi dare a tutti la stessa chiave, chiavi diverse o loro.

Codice sorgente pubblicato

Memorizzi il codice sorgente in un repository pubblico ma non nella KEY. Nella configurazione del file aggiungi le linee * inserisci la chiave qui * . Quando uno sviluppatore utilizza il tuo codice sorgente, crea una copia del file sample.cfg e aggiunge la propria chiave.

Non conservi il tuo file config.cfg utilizzato per lo sviluppo o la produzione nel repository.

    
risposta data 23.07.2013 - 21:28
fonte
5

Utilizza le variabili d'ambiente per le cose segrete che cambiano per ogni server.

link

Come usarli dipende dalla lingua.

    
risposta data 23.07.2013 - 20:39
fonte
4

Penso che questo sia un problema che tutti hanno avuto qualche problema ad un certo punto.

Ecco un flusso di lavoro che ho utilizzato, che potrebbe funzionare per te. Utilizza .gitignore con una svolta:

  1. Tutti i file di configurazione vanno in una cartella speciale (con i file di configurazione di esempio - facoltativo)
  2. Tutti i file di configurazione sono inclusi in .gitignore, in modo che non diventino pubblici
  3. Imposta un server gitolite (o il tuo server git preferito) su una casella privata
  4. Aggiungi un repository con tutti i file di configurazione nel server privato
  5. Aggiungi uno script per copiare i file di configurazione nella cartella speciale nel repository principale (facoltativo)

Ora è possibile clonare il repository di configurazione in qualsiasi sistema di sviluppo e implementazione. Basta eseguire lo script per copiare i file nella cartella corretta e il gioco è fatto.

Hai ancora tutte le caramelle GitHub, condividi il tuo codice con il mondo e i dati sensibili non sono mai nel repository principale, quindi non diventano pubblici. Sono ancora solo una copia e una copia lontana da qualsiasi sistema di distribuzione.

Uso una casella da 15 $ / anno per il server git privato, ma puoi anche installarne una a casa, secondo i requisiti di cheapskate; -)

PS: potresti anche usare un sottomodulo git ( link ), ma dimentico sempre i comandi, quindi veloce e amp; regole sporche!

    
risposta data 08.12.2013 - 22:24
fonte
2

Usa la crittografia, ma fornisci una chiave master all'avvio, come password sulla console, in un file che solo l'utente del processo può leggere, o da un keystore fornito dal sistema come il portachiavi Mac OS o il keystore di Windows.

Per la consegna continua, dovrai registrare varie chiavi da qualche parte. La configurazione dovrebbe essere delimitata dal codice, ma ha molto senso tenerlo sotto controllo di revisione.

    
risposta data 23.07.2013 - 12:15
fonte
1

3 strategie, non ancora menzionate (?)

Al check-in o in un pre-controllo VCS nel gancio

  • cerca stringhe con alta entropia, ad esempio- detect-secrets
  • regex la ricerca di modelli di chiavi API ben noti. I tasti AKIA * di AWS sono un esempio, git-secrets è uno strumento basato su questo. Inoltre, nomi variabili come "password" con assegnazione costante.
  • cerca i segreti conosciuti- conosci i tuoi segreti, cerca il testo per loro. O usa uno strumento, ho scritto questo proof of concept .

Strategie già citate

  • memorizza file all'esterno dell'albero dei sorgenti
  • averlo nell'albero dei sorgenti, ma di dire a VCS di ignorarlo
  • Le variabili d'ambiente
  • sono una variazione sull'archiviazione dei dati al di fuori dell'albero sorgente
  • semplicemente non dare i preziosi segreti agli sviluppatori
risposta data 24.07.2018 - 05:02
fonte
0

Tieni le informazioni private fuori dal tuo controllo del codice sorgente. Crea un valore predefinito non caricato per la distribuzione e fai in modo che il tuo VCS ignori quello reale. Il processo di installazione (manuale, configurazione / creazione o procedura guidata) dovrebbe gestire la creazione e la compilazione del nuovo file. Modificare facoltativamente le autorizzazioni sul file per garantire che solo l'utente richiesto (server web?) Possa leggerlo.

I vantaggi:

  • Non assume entità di sviluppo == entità di produzione
  • Non presuppone che tutti i collaboratori / revisori del codice siano affidabili
  • Prevenire errori semplici mantenendoli fuori controllo di versione
  • Facile da automatizzare le installazioni con configurazione personalizzata per QA / build

Se lo stai già facendo e lo accetti accidentalmente, aggiungilo alla .gitignore del tuo progetto. Ciò renderà impossibile fare di nuovo.

sono un sacco di host Git gratuiti che forniscono repository privati. Anche se non dovresti mai creare le tue credenziali, puoi essere a buon mercato e avere anche dei repository privati. ^ _ ^

    
risposta data 27.07.2013 - 06:40
fonte
-2

Invece di avere la chiave OAuth memorizzata come dati non elaborati ovunque, perché non eseguire la stringa attraverso un algoritmo di crittografia e archiviarla come hash salato? Quindi utilizzare un file di configurazione per ripristinarlo in fase di runtime. In questo modo la chiave non viene memorizzata da nessuna parte, sia che sia memorizzata su una scatola di sviluppo, sia sul server stesso.

Potresti anche creare un'API in modo che il tuo server generi automaticamente una nuova chiave API salata e con hash su base per richiesta, in questo modo nemmeno il tuo team può vedere la fonte OAuth.

Modifica: forse prova la libreria di crittografia Javascript di Stanford , consente una crittografia / decodifica simmetrica abbastanza sicura.

    
risposta data 23.07.2013 - 22:19
fonte