API anahtarları gibi gizli bilgilerin kaynak kontrolünün dışında tutulması stratejisi?


217

Kullanıcıların Twitter, Google, vb. OAuth kimlik bilgilerini kullanarak giriş yapmalarına izin verecek bir web sitesinde çalışıyorum. çeşitli vücut parçalarına karşı rehinlerle korumak için. Anahtarım susturulursa, parça yanmış.

API anahtarının, çalışma zamanında kimlik doğrulama isteklerini gerçekleştirmek için kullanıldığı için kaynağımla seyahat etmesi gerekiyor. Benim durumumda, anahtar uygulama içinde bir yapılandırma dosyasında veya kodun içinde bulunmalıdır. Tek bir makineden oluşturup yayınladığımda sorun değil. Bununla birlikte, karışıma kaynak kontrolü attığımızda işler daha da karmaşıklaşıyor.

Ucuz bir piç olduğum için bulutta veya GitHub gibi TFS gibi ücretsiz kaynak kontrol hizmetlerini kullanmayı tercih ederim. Bu bana hafif bir bilmece bırakır:

API anahtarlarım kodumdayken ve kodum halka açık bir depoda olduğunda vücudumu nasıl koruyabilirim?

Bununla başa çıkmanın birkaç yolunu düşünebilirim, ancak hiçbiri tatmin edici değil.

  • Tüm özel bilgileri koddan kaldırabilir ve dağıtımdan sonra yeniden düzenleyebilirim. Bu, uygulanacak ciddi bir acı olacaktır (birçok yolu ayrıntılandırmam) ve bir seçenek değildir.
  • Şifreleyebilirim. Ancak şifresini çözmem gerektiğinden, kaynağı olan herkes bunun nasıl yapıldığını çözebilir. Anlamsız.
  • Özel kaynak kontrolü için ödeme yapabilirim. Lol j / k para harcamak? Lütfen.
  • Hassas özellikleri kaynağımın geri kalanından ayırmak için dil özelliklerini kullanabilir ve bu nedenle kaynak denetiminde tutabilirim. Şimdi ne yapıyorum, ama yanlışlıkla gizli dosyayı kontrol ederek kolayca berbat olabilir.

Gelişme, hata ayıklama ve konuşlandırma yoluyla sorunsuzca çalışacak ve aynı zamanda kusursuz davranacak özel ürünlerimi dünya ile paylaşmamamı (anlık görüntü dışında) da garanti etmenin gerçekten garantili bir yolunu arıyorum. Bu tamamen gerçekçi değil. Peki gerçekçi olarak ne yapabilirim?

Teknik detaylar: VS2012, C # 4.5, kaynak kontrolü ya TF servisi veya GitHub olacak. Şu anda, hassas tuşları kaynak kontrolüne eklenmeyecek ayrı bir .cs dosyasında bölmek için kısmi bir sınıf kullanıyor. GitHub, .gitignore'un kısmi sınıf dosyasının teslim edilmediğinden emin olmak için kullanılabileceği gibi bir avantaja sahip olabileceğini düşünüyorum, ancak bunu daha önce berbat ettim. "Ah, ortak bir sorun, bunu nasıl yaptığınız" umuduyla, ancak "sahip olabileceği kadar emmez" için yetinmek zorunda kalabilirim: /


6
API anahtarınızı tutan konfigürasyon dosyasının kaynak kontrollü dizinde olmadığından emin olabilirsiniz, bu da ilk etapta kontrol etmenizi imkansız hale getirir.
David Sergey,

22
BitBucket.org'un sınırsız özel depoları vardır. Beleş. Ve gitHub depo ithalatçısı (tarihini koruyor)
Rob van der Veer

4
@Dainius Geliştiricilerime güvenmiyorum, çünkü onları biliyorum. Samimiydik. Aslına bakarsan en azından kendi kendime karşı yakınım ... hayır, onun yalan söylemesine izin vereceğim. Ama berbat etmenin ne kadar kolay olduğunu ve söylenen berbat tarihçeyi temizlemenin ne kadar zor olduğunu biliyorum.
Will

15
@Dainius: Evet. Takım kodlarımın her karakterine bakıyorum. Ciddi anlamda. Başka seçeneğim yok. Gözü kapalı kodlayamam. En azından güvenilir bir şekilde değil. Ama yapıyorum çünkü benim takımım. Ben EKİ'deki benim. Bir geliştirici var ve benim. Ben o Evet. Doğru yapmazsa bunu mahvedecek adam benim. Ben mi.
Will

3
Neden en başta anahtarı kodun içinde derlemeye çalışıyorsun? Bu tür bir şeyi bir yapılandırma dosyasına koymak normaldir.
Donal Fellows,

Yanıtlar:


128

Gizli bilgilerinizi kodunuza koymayın. Başlangıçta kodunuzla okunan bir yapılandırma dosyasına yerleştirin. Yapılandırma dosyaları "fabrika varsayılanları" olmadıkça sürüm kontrolüne alınmamalı ve özel bilgileri içermemelidir.

Bunun nasıl yapıldığını öğrenmek için Sürüm kontrolü ve kişisel yapılandırma dosyası sorusuna da bakın .


8
@RobertHarvey sadece sürüm kontrolüne koyarak değil, gerektiğinde yoksayma kuralı ekleyerek. Yazılımı kullanan herkes kendi yapılandırma dosyasını kendi API anahtarıyla oluşturmalıdır.
Philipp,

10
Öyleyse, yazılımınızın dağıtımını oluşturup oluşturduğunuzda, bir yapılandırma dosyasıyla birlikte verildiğinden nasıl emin olabilirsiniz? Makul varsayılanlara sahip bir dosyanız olmadıkça, kullanıcının bir yapılandırma dosyası oluşturma sürecinden geçmesini beklemeniz makul değildir.
Thomas Owens

4
Fabrika varsayılanları bir bölüm, "yükleyiciler" veya "ilk çalıştırma sihirbazları" diğeridir
johannes

6
Birçok kullanıcının kendi yüklemesi varsa, kendi API anahtarını oluşturup kullanmamalıdırlar mı? Aynı anahtarı kullanarak birden fazla site / yükleme muhtemelen kötü bir fikirdir. Sadece bir yükleme ise, bir yapılandırma dosyası kullanmak büyük bir zorluk değildir.
Mike Weller

10
@ Bunu yaparken, uygulama detaylarının pratik olmayışı nedeniyle bunu yapamazsanız, o zaman konuşlandırma için uygun donanıma sahip olmadığınızı söyleyebilirim. Sınırlandırılmamış bir gizli config dosyası kullanarak konuşlandırma tamamen ağrısız olmalıdır. Ruby ekosisteminde yaşadığımdan beri size özel bir tavsiyede bulunamıyorum, C # yerine. Ancak Ruby insanları Capistrano'yu otomatik dağıtımlar için kullanma eğilimindedir. C # 'ın otomatik dağıtım için de bir aracı olduğundan eminim ve bu işlemi kolaylaştıracak.
Ben Lee

29

Tüm özel / korumalı anahtarları sistem ortamı değişkenleri olarak koyabilirsiniz. Yapılandırma dosyanız şöyle görünecek:

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

Bu davaları böyle ele alıyoruz ve hiçbir şey koda girmiyor. Farklı özellik dosyaları ve profilleri ile birlikte çok iyi çalışıyor. Farklı ortamlar için farklı özellik dosyaları kullanıyoruz. Yerel geliştirme ortamımızda, yerel kurulumu kolaylaştırmak için geliştirme anahtarlarını özellik dosyalarına koyarız:

private.key=A_DEVELOPMENT_LONG_KEY

Bu benim barındırma seçeneği ile çalışmak için alabilirsiniz eğer bu makul bir çözüm olacaktır. Çevre değişkenleri, ancak yayınlandıktan sonra sildi alamadım belki bazı anahtar / değer yapılandırma çiftleri ... olmayacak
Will

Canlı ortama göndermeden önce bu ortam değişkenlerini build sunucunuza yerleştirmeye ne dersiniz? Bu şekilde üretim kaynak / konfigürasyon dosyaları için hazır olacaksınız.
Ioannis Tzikas

Yapım sunucusu geliştirme makinesidir, bu nedenle bu bilgilerin yanlışlıkla kontrol altına alınmasından endişeleniyorum.
Will

Bununla ilgili sorun, ortamın sunucudaki herhangi biri tarafından okunabilmesi olabilir.
JasonG

Bir kullanıcının envvarları sadece kullanıcı veya root tarafından okunabilir. (Eski Linux ve AIX bunu yapmadı)
Neil McGuigan

27

Saf Git yolu

  • .gitignore özel veri içeren dosya
  • Hangi değiştirmek, yerel bir şube kullanın TEMPLATEileDATA
  • (Yerel) filtrenin komut dosyasının çift yönlü değiştirme gerçekleştirdiği lekeli / temiz filtreler kullanın TEMPLATE<->DATA

Mercurial yol

  • Yerine kukla kod, üst üste MQ-yama (ler) TEMPLATEile DATA(changesets kamuya açıktır, yama özeldir)
  • Özel tasarlanmış anahtar kelimelere sahip anahtar kelime uzantısı (yalnızca çalışma dizininizde genişletilmiş )

SCM-agnostik yol

  • Anahtar kelimeleri değiştirme işleminin bir parçası olarak kullanın.

Hmmm ... Git tavsiyesi iyidir ve agnostik tavsiyeniz bana iyi bir fikir verir ... Dosyayı yayınlama sürecine tanıtmak için derleme olayları kullanabilirim, sonra silebilirim, böylece yapmamasını sağlamaya yardımcı olurum yanlışlıkla kaynak kontrolü eklenebilir ..
Will

7
Hayır, hayır ve bir kez daha - hayır! Dosyaları yoksaymak, işlemi veya başka bir şeyi oluşturmak için çok özel bir özelleştirme eklemek için iyidir, ancak hiçbir zaman güvenli verileri depolamak için kullanılmamalıdır. Görmezden gelseniz bile, güvenli verileri depoda saklamayın.
shabunc

11
@ shabunc - RTFM! Yok Sayılan dosya saklanmaz repo
Tembel Badger

9
@LazyBadger - Ben göz ardı edildiğini oldukça iyi biliyorum. Ayrıca, repoda olmanın, HER ZAMAN birisinin yanıltıcı bir şekilde repoyu bir şekilde ekleyebilme şansı olduğunu da biliyorum. Bazı harici yapılandırma yolu çok daha iyi.
shabunc

4
@ shabunc - config ayarını SCM yolundan uzak tutmanın iyi noktası. Bu nedenle örneğin Postgres, şifreyi bir dosyaya koyarak şifre kontrollerini atlamanıza izin verir. Ancak, şifre dosyasının ~ / .pgpass içine koyulmasını gerektirir - bu muhtemelen kaynak kontrolünü kontrol etmek için çok uygun bir yer değildir. Biliyorlar ki, otomasyon için, size bir silah vermek zorundalar, ancak sizi onunla birlikte vurmaktan
kaçınmak için çok

14

Sırları sonra işlediğim şifreli dosyalara koydum. Parola sistemi başlatıldığında verilir veya işlemediğim küçük bir dosyada saklanır. Emacs'in bu şifreli dosyaları neşeyle yönetmesi çok güzel. Örneğin, emacs init dosyası şunları içerir: (sadece "gizlis.el.gpg" yükle) çalışır - editöre başladığımda bu nadir görülen durumların şifresini ister. Birisinin şifreyi kırması konusunda endişelenmiyorum.


3
Bu harika bir çözüm - daha fazla oy almamaya şaşırdım. ABD’de federal olarak düzenlenmiş öğrenci verileriyle ilgilenen bir şirketle çalışıyorum, bu yüzden kimlik bilgileri ve sırlarıyla daha dikkatli olmaları gerekiyor. Aynı zamanda büyük bir şirketlerdir, bu nedenle bilgi birikimi için SCM'yi kullanmaları gerekir, böylece BT onları kurduktan sonra onları bulabilir / yönetebilir. Çözümünüz tam olarak yaptıkları şeydir. Dev / staging / prod / etc (her biri için bir dosya) için deşifre anahtarlarını tutan anahtar dosyalarının şifresini çözerler. Sonra tüm sırlar şifrelenir ve dosyalara eklenir. Şifre çözme dosyaları, her ortamda onları almak için kullanılır.
Steve Midgley

7
Eh, gizli (bu durumda API anahtarı) şifreleyerek Bir anlamda sadece gelen sorun kaydırır gizli verileri işlemekten değil için geçiş deyimini işlemekten değil (şimdi olur gizli verileri ). Fakat elbette, sisteme giriş sırasında bunu sormak iyi bir seçenektir.
siegi

Bu çözümü sevdim. İşlediğiniz şifreli dosyanın türü bir KeePass dosyası olabilir. Her ortam için, notes.env dosyasının içeriğini depolamak için alanı kullanarak bir girişi olacaktır . Birkaç ay önce bir keepass dosyasını okuyabilen ve notesbir giriş alanını kullanarak bir .env dosyası yaratabilen bir araç yazdım . require('switchenv').env()Node.js programının başında yapabileceğim ve NODE_ENV ile aynı olan bir girişe dayanarak process.env değişkenleri oluşturabileceğim bir özellik eklemeyi düşünüyorum . -> github.com/christiaanwesterbeek/switchenv
Christiaan Westerbeek

14

Bu çok Android / Gradle özgüdür, ancak içinde gradle.propertiesbulunduğunuz global dosyanızdaki anahtarları tanımlayabilirsiniz user home/.gradle/. Bu, buildType veya flavor'a bağlı olarak farklı özellikleri kullanabildiğinizden, yani dev için API ve sürüm için farklı olanlardan da yararlanabileceğiniz için de kullanışlıdır.

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"
            }
        }

Kodda buna benzer

String myAPI = BuildConfig.GOOGLE_VERIFICATION_API_KEY;

BuildConfig karşılık gelen kaynak dosyasına çevirir, bu nedenle apk'nizdeki basit ters mühendislik, BuildConfig
Dmitri Livotov

1
Gerçekten geçerli bir nokta. Ancak soru api anahtarlarını ikili koddan değil kaynak kodundan nasıl uzak tutacağımızla ilgiliydi.
scottyab

11

Bu anahtarı uygulamanızla dağıtmanız veya kaynak kod deposunda saklamanız gerekmiyor. Bu soru bunun nasıl yapılacağını soruyor ve normalde yapılan şey bu değil.

Mobil Web Uygulaması

Android / iPhone için, uygulama ilk çalıştırıldığında cihaz KEY'i kendi web servisinizden istemelidir. Anahtar daha sonra güvenli bir yerde saklanır. Anahtarın yayıncı tarafından değiştirilmesi veya iptal edilmesi gerekir. Web servisiniz yeni bir anahtar yayınlayabilir.

Barındırılan Web Uygulaması

Yazılımınızın lisansını kullanan müşterilerin, yazılımı ilk kez yapılandırırken anahtarı manuel olarak girmeleri gerekir. Herkese aynı anahtar, farklı anahtarlar verebilir veya kendi anahtarlarına sahip olabilirsiniz.

Yayınlanan Kaynak Kod

Kaynak kodunuzu genel bir depoda saklayabilirsiniz, ancak ANAHTAR değil. Dosyanın konfigürasyonunda satırları * yer anahtarını buraya * ekleyin . Bir geliştirici kaynak kodunuzu kullandığında, sample.cfgdosyanın bir kopyasını çıkarır ve kendi anahtarını ekler.

Eğer tutmuyorum config.cfgdepoda geliştirme veya üretim için kullanılan dosya.


4
Bu soru nasıl yapılacağını soruyor , kesinlikle değil. Gerçek şu ki, bu anahtarların kodla kullanılması gerekir, bu nedenle kodla erişilir ve bu genellikle kaynak veya kaynak kodlu bir dosyada olmadıkları takdirde kod veya konfigürasyon dosyaları anlamına gelir. kaynak. Barındırılan web uygulaması ne yazık ki saçma. (Varsayımsal) facebook hesabınız aracılığıyla StackOverflow'a giriş yapmak için bir api anahtarına başvurmanıza gerek yoktu. Burada yer anahtar Q açıklanan olarak dev-> pub ortamlarını çalışmaz büyük bir basite indirgeme
Will

Soruyu doğru cevapladım, diğerleri olduğu gibi. Bunlardan birini kabul etmemiş olmanız, bu anahtarlarla nasıl çalışılacağını anlamadığınız anlamına gelir.
Reactgular

7
Öyleyse, anahtar yayınlayan web servisini nasıl koruruz? Başka bir anahtar mı kullanıyorsunuz?
Jiangge Zhang,

@JianggeZhang'ın söylediği gibi - bu tehlikeli bir tavsiye
David K. Hess

5

Her sunucu için değişen gizli şeyler için ortam değişkenlerini kullanın.

http://en.wikipedia.org/wiki/Environment_variable

Bunları nasıl kullanacağınız dile bağlıdır.


3
Müstehcenlik yoluyla güvenlik birçokları için önerilen bir yaklaşım değildir. Daha net olmak için cevabınızı detaylandırmak ister misiniz?

2
Bu belirsizlik değildir, ortam değişkenleri yalnızca eklediğiniz kullanıcılar tarafından kullanılabilir, bu nedenle tüm kimlik bilgileriniz uygulamanızın çalıştığı kullanıcı bağlamında aynı korumayı sağlar. Cevabı çevre değişkenleri kavramını içerecek şekilde güncelledim. Bu daha açık mı?
Filipe Giusti

4

Bence bu, herkesin bir noktada sorun yaşadığı bir konu.

İşte kullandığım, sizin için işe yarayabilecek bir iş akışı. Bir bükülme ile .gitignore kullanır:

  1. Tüm yapılandırma dosyaları özel bir klasöre gider (örnek yapılandırma dosyaları ile - isteğe bağlı)
  2. Tüm konfigürasyon dosyaları .gitignore'a dahil edilmiştir, böylece herkese açık olmazlar
  3. Özel bir kutuda bir gitolit sunucusu (veya favori git sunucunuz) kurun
  4. Özel sunucudaki tüm config dosyalarıyla bir repo ekle
  5. Yapılandırma dosyalarını ana depodaki özel klasöre kopyalamak için bir komut dosyası ekleyin (isteğe bağlı)

Artık config repo'yu herhangi bir geliştirme ve dağıtım sistemine kopyalayabilirsiniz. Dosyaları doğru klasöre kopyalamak için betiği çalıştırmanız yeterlidir.

Hala tüm GitHub şekerlerini alıyorsunuz, kodunuzu dünyayla paylaşıyorsunuz ve hassas veriler hiçbir zaman ana depoda değil, bu yüzden halka açılmıyorlar. Hala herhangi bir dağıtım sisteminden yalnızca bir çekip kopardılar.

Özel git sunucusu için 15 $ / yıllık bir kutu kullanıyorum, ancak cheapskate şartı uyarınca evde bir tane de ayarlayabilirsiniz ;-)

Not: Git alt modülünü de kullanabilirsiniz ( http://git-scm.com/docs/git-submodule ), ancak komutları her zaman unutuyorum, çok hızlı ve kirli kurallar!


2

Şifrelemeyi kullanın, ancak başlangıçta, konsolda bir şifre olarak, yalnızca işlemin kullanıcısını okuyabileceğiniz bir dosyada veya Mac OS anahtar zinciri veya Windows anahtar deposu gibi sistem tarafından sağlanan bir anahtar deposundan bir ana anahtar sağlayın.

Sürekli teslimat için bir yere kaydedilmiş çeşitli anahtarlar isteyeceksiniz. Yapılandırma koddan ayrı tutulmalıdır, ancak revizyon kontrolü altında tutulması çok mantıklıdır.


1

3 Henüz belirtilmeyen stratejiler (?)

Check-in veya VCS kontrolünde kancada ön kontrol

  • yüksek entropiye sahip dizeleri aramak, example - detector -secrets
  • regex iyi bilinen API anahtar kalıplarını araştırıyor. AWS'nin AKIA * anahtarları bir örnektir, git-secrets buna dayanan bir araçtır. Ayrıca sürekli atama ile 'şifre' gibi değişken isimler.
  • bilinen sırları araştırın - sırlarınızı biliyorsunuz, onlar için metin arayın. Ya da bir araç kullanın, bu kavram kanıtını yazdım .

Daha önce bahsedilen stratejiler

  • kaynak ağacın dışındaki dosyada sakla
  • kaynak ağacında bulundurun, ancak VCS'ye bunu görmezden gelmesini söyleyin
  • ortam değişkenleri, verilerin kaynak ağacın dışında depolanmasındaki bir varyasyondur.
  • sadece geliştiricilere değerli sırları verme

0

Özel bilgileri kaynak kontrolünüzden uzak tutun. Dağıtım için yüklü olmayan bir varsayılan oluşturun ve VCS'nizin gerçek olanı yoksaymasını sağlayın. Yükleme işleminiz (kılavuz, yapılandırma / derleme veya sihirbaz) yeni dosyanın oluşturulmasını ve doldurulmasını işlemelidir. İsteğe bağlı olarak yalnızca gerekli kullanıcının (web sunucusu?) Okuyabilmesini sağlamak için dosya üzerindeki izinleri değiştirin.

Yararları:

  • Geliştirme kuruluşu varsayılmıyor mu == üretim varlığı
  • Tüm ortak çalışanların / kod gözden geçirenlerin güvenilir olduğunu varsaymaz
  • Sürüm kontrolünün dışında tutarak kolay hataları önleyin
  • KG / yapı için özel konfigürasyon ile kurulumları otomatikleştirmek

Zaten bunu yapıyorsanız ve yanlışlıkla kontrol ediyorsanız, projenize ekleyin .gitignore. Bu tekrar yapmayı imkansız hale getirir.

Orada olan özel depoları sağlamak etrafında serbest Git ana bol. Asla kimlik bilgilerinizi sürümlendirmemelisiniz, ancak ucuz ve özel repolarınız olabilir. ^ _ ^


-2

OAuth anahtarının herhangi bir yerde ham veri olarak saklanması yerine, neden bazı şifreleme algoritmalarıyla dizgiyi çalıştırmıyorsunuz ve tuzlu bir karma olarak saklamıyorsunuz? Sonra çalışma zamanında geri yüklemek için bir yapılandırma dosyası kullanın. Bu şekilde, anahtar bir geliştirme kutusunda veya sunucunun kendisinde depolanmış olsun, hiçbir yerde depolanmaz.

Sunucunuz otomatik olarak istek üzerine yeni bir tuzlu ve karma API anahtarı oluşturacak şekilde bir API bile oluşturabilirsiniz, böylece ekibiniz bile OAuth kaynağını göremez.

Düzenleme: Belki Stanford Javascript Kripto Kütüphanesi deneyin, bazı oldukça güvenli simetrik şifreleme / şifre çözme için izin verir.


1
Hash'ler genellikle tek yönlü karıştırışlardır. Yine de önerdiğin gibi yapacak olan simetrik şifreleme algoritmaları var.

3
Dostum, bir karmaşanın şifresini çözemezsin (kolayca). Bu bütün karmaşa noktası. Bu, ME’nin bir başkasının API’sini tüketmesi içindir; Bunu benim değerlemem (her seferinde kötü bir algo seçip kırmadığım sürece) API'larını kullanmamamı sağlıyor.
Will
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.