2 puan yazan GN⁺ 2024-05-08 | 1 yorum | WhatsApp'ta paylaş
  • Go 1.22'de hem mevcut math/rand paketi hem de yeni sunulan math/rand/v2 paketi, kriptografik olarak güvenli bir rastgele sayı üreteci kullanacak şekilde değiştirildi. Böylece daha iyi rastgelelik sağlanıyor ve geliştiricilerin yanlışlıkla crypto/rand yerine math/rand kullanması durumunda ortaya çıkabilecek zarar büyük ölçüde azaltılıyor.

İstatistiksel rastgelelik ile kriptografik rastgelelik arasındaki fark

  • İstatistiksel rastgelelik; simülasyon, örnekleme, sayısal analiz, kriptografik olmayan rastgele algoritmalar, rastgele testler, girdi karıştırma ve rastgele üstel backoff gibi kullanım alanları için uygundur.
  • Çok temel ve hesaplaması kolay matematiksel formüller bile bu tür amaçlar için yeterince iyi çalışabilir. Ancak kullanılan algoritmayı bilen bir gözlemci, belirli sayıda değeri gördükten sonra sonraki diziyi tahmin edebilir.
  • Kriptografik rastgelelik ise, daha önce üretilmiş herhangi bir sayıda değeri gözlemlemiş olunsa bile pratikte tamamen öngörülemez olmalıdır.
  • Güvenli şifreleme protokolleri, gizli anahtarlar, modern ticaret ve çevrimiçi gizlilik büyük ölçüde kriptografik rastgeleliğe dayanır.

Go 1'in math/rand üreteci

  • Linear-feedback shift register (LFSR) yöntemi kullanır.
  • İç durumunun, 607 adet uint64'ten oluşan bir vektör olarak tamamen açığa çıkabilmesi gibi bir sorunu vardır.
  • Üreteçten 607 değer okunursa tüm durum ortaya çıkar ve sonraki değerler tahmin edilebilir.

math/rand/v2 içindeki PCG üreteci

  • Melissa O'Neill'ın PCG algoritmasını kullanır. Bu, 128 bitlik bir LCG üzerine son işlem uygulanmış bir yapıdır.
  • Tüm durum tek bir 128 bitlik sayıdan oluşur; güncelleme ise 128 bit çarpma ve toplama ile yapılır.
  • Go, O'Neill'ın önerisine uygun olarak XOR tabanlı yerine çarpma tabanlı bir scramble işlevi kullanarak bitleri daha agresif biçimde karıştırır.
  • Go 1 üretecine göre daha fazla hesaplama gerektirir, ancak durum saklamak için çok daha az bellek ister, başlangıç durumu değerlerine daha az duyarlıdır ve diğer üreteçlerin geçemediği istatistiksel testleri de geçer.
  • Ancak PCG de hâlâ öngörülemez değildir.

Kriptografik rastgelelik

  • Nihayetinde işletim sisteminin fiziksel aygıt gürültüsünden gerçek rastgelelik toplaması gerekir.
  • Yeterli rastgelelik (256 bit veya daha fazlası) toplandığında, bu değer kriptografik hash ya da şifreleme algoritmalarıyla genişletilerek istenen uzunlukta rastgele sayı dizileri üretilebilir.
  • Go'nun crypto/rand paketi bu işletim sistemi arayüzü farklarını soyutlar ve aynı rand.Read arayüzünü sunar.

ChaCha8Rand üreteci

  • DJB'nin ChaCha akış şifresinin değiştirilmiş hâliyle oluşturulmuş yeni bir üreteçtir.
  • 8 turlu sürüm olan ChaCha8'i kullanır. ChaCha20'den 2,5 kat daha hızlıdır ve yine de güvenlidir.
  • 32 baytlık seed, ChaCha8 anahtarı olarak kullanılır. Her 16 blokta bir, üretilen blokların son 32 baytı sonraki 16 bloğun anahtarı olarak kullanılarak ileriye dönük gizlilik sağlanır.
  • math/rand/v2 içindeki rand.Float64, rand.N vb. her zaman bu üreteci kullanır.
  • math/rand da bu üreteci kullanır. Ancak rand.Seed çağrılırsa Go 1 üreteci kullanılır.
  • Runtime da yeni map'lerin hash seed'ini seçerken ChaCha8Rand kullanır.

Güvenlik hatalarının giderilmesi

  • Go 1.22, math/rand'i güçlendirerek kod değişikliği olmadan bile programları daha güvenli hâle getirir.
  • Örneğin math/rand içindeki Read yanlışlıkla anahtar üretimi gibi amaçlarla kullanılmışsa, bu durum Go 1.20'de ciddi bir güvenlik sorunu iken Go 1.22'de sadece bir hataya dönüşür.
  • UUID üretimi ya da frontend sunucularında yük dağıtımı gibi "kripto" gibi görünmeyen kullanımlarda bile, ChaCha8Rand kullanmak Go 1 üretecine göre çok daha dayanıklıdır.

Performans

  • ChaCha8Rand, Go 1 üreteci ya da PCG ile benzer düzeyde performans gösterir.
  • 32 bitlik kodda, 128 bit çarpma gerektiren PCG'ye kıyasla ChaCha8Rand daha hızlıdır.
  • math/rand/v2 içindeki, 64 bit bölmeden kaçınan algoritmalar sayesinde N(1000) işleminde ChaCha8Rand veya PCG'nin Go 1 üretecinden daha hızlı olduğu durumlar da vardır.
  • Genel olarak ChaCha8Rand, Go 1 üretecinden daha yavaştır ancak hiçbir durumda 2 kattan fazla yavaş değildir ve tipik sunucularda fark 3ns'yi aşmaz.

GN⁺ görüşü

  • Go 1.22'de ChaCha8Rand'in uygulanması, güvenliği büyük ölçüde artırırken performans kaybını minimumda tutan, dil düzeyinde örnek bir iyileştirme sayılabilir. Geliştiricilerin sık yaptığı hataların dil seviyesinde en baştan engellenmiş olması etkileyici.
  • Metinde de belirtildiği gibi bu tür hatalar yalnızca Go'ya özgü değil; diğer dillerde de sık görülüyor. Geliştirici hatalarının sistem güvenliğini belirlememesi gerektiğinden, diğer dillerin de Go gibi "matematiksel" rastgele sayı üretiminde kriptografik olarak güçlü sözde rastgele sayı üreteçlerine yönelmesi gerekir.
  • Ancak ChaCha8Rand, crypto_box ya da xchacha20poly1305 gibi kriptografik primitive'lerde kullanılmak için uygun değildir. Bu tür kullanımlarda yine doğrudan crypto/rand kullanılmalıdır.
  • Go runtime'ının map hash seed seçimi için de ChaCha8Rand kullanacak şekilde değiştirilmiş olması biraz şaşırtıcıydı. Hash seed için kriptografik rastgeleliğin mutlaka gerekli olup olmadığı net olmasa da, zahmetli saldırı olasılıklarını en baştan ortadan kaldırma isteğini gösteren güçlü bir güvenlik yaklaşımı dikkat çekiyor.
  • Dilin standart paketi olan math/rand'in kalitesi yükseldiğine göre, bundan sonra uygulamalarda math/rand'i doğrudan kullanma durumu da daha sık görülebilir. Şimdiye kadar math/rand'in öngörülebilirliği nedeniyle ayrı rastgele sayı üretim kütüphaneleri kullanan projeler bu değişiklikten fayda görebilir.

1 yorum

 
GN⁺ 2024-05-08
Hacker News görüşü

Özetle şöyle:

  • Go 1.20'de math/rand paketindeki Read fonksiyonu deprecated edildiğinde, bunun crypto/rand yerine hatalı kullanıldığı örnekler görüldü. Bu da güvenlik açısından zayıf, deterministik bir rastgele sayı üretecinin kullanılmasına yol açan hatalara neden oldu.
  • Go'nun varsayılan rastgele sayı üretecini CSPRNG'ye (kriptografik olarak güvenli sözde rastgele sayı üreteci) çevirmek, güvenlik açısından daha iyi bir yaklaşım. Açıkça PRNG gereken durumlarda yalnızca onun seçilmesi daha uygun.
  • gosec ve golangci-lint gibi statik analiz araçları, math/rand kullanımına karşı uyarı veriyor.
  • math/rand/v2 paketi ChaCha8 şifresini kullanıyor ve sistem entropisiyle seed ediliyor; bu da "güvenli" bir izlenim veriyor, ancak yine de güvenliğe duyarlı işler için uygun değil. Bu tür durumlarda crypto/rand kullanılmalı.
  • Go 1'deki math/rand, daha teknik olarak additive lagged Fibonacci generator olarak görülebilir.
  • Yeni math/rand, en kötü durumda bile önceki güvensiz rastgele sayı üretecinin yaklaşık yarısı kadar hız gösterdi ve çoğu benchmark'ta neredeyse fark yoktu. Go, standart kütüphanede güvenlik ile performans arasında uygun bir denge kuruyor.
  • Bunun, Java'daki java.util.Random benzeri hataları önleyen geliştirici dostu bir yaklaşım olduğu düşünülüyor.
  • Neden ChaCha8 kullanıldığı ve neden AES-GCM gibi donanım hızlandırma destekli blok şifrelerin tercih edilmediği sorusu gündeme geliyor.