Bu neden önemli?
Şifrelemenin bütün gücü rastgeleliğe dayanıyor. Rastgele sayı yeterince rastgele değilse, en sağlam kilit bile birkaç saatlik tahmin işine döner. Bu olay, küçük bir derleme hatasının nasıl dev bir güvenlik açığına dönüştüğünü gösteriyor.
Donanım cüzdanı ne işe yarar?
Bitcoin’in sahibi, onun gizli anahtarını bilen kişidir. Bu anahtar genelde 12 ya da 24 kelimelik bir seed (tohum) ifadesinden türetilir. Kelimeleri bilen, parayı harcayabilir.
Donanım cüzdanı, bu anahtarı internete bağlı bir bilgisayardan uzakta tutan küçük bir cihaz. Coinkite’ın Coldcard’ı bu alanda en güvenlik odaklı seçeneklerden biri olarak biliniyordu. Hatta internete hiç bağlanmadan kullanılabiliyordu.
Ama bir sorun vardı: Seed’i üreten de cihazın kendisiydi.
Rastgelelik neden bu kadar önemli?
12 kelimelik bir seed, 128 bitlik rastgelelikten üretilir. Bu, yaklaşık 3,4 × 10³⁸ farklı olasılık demek. Dünyadaki bütün bilgisayarlar birlikte çalışsa bile hepsini denemek imkânsız.
Ama bu hesap tek bir şarta bağlı: Sayılar gerçekten rastgele olmalı. Güvenlik uzmanları buna entropi diyor. Coldcard, bu iş için çipin içindeki donanımsal rastgele sayı üretecini (RNG) kullanmak üzere tasarlanmıştı.
Hata nerede?
Mart 2021’de yazılımda bir kütüphane değişikliği yapıldı. Kodun bir yerinde şu mantık vardı: “Donanım RNG ayarı tanımlı mı?” Oysa sorulması gereken “Donanım RNG ayarı açık mı?” idi.
Coldcard’ın yapılandırmasında bu ayar tanımlıydı ama değeri sıfırdı. C dilindeki #ifndef kontrolü sadece tanımlı olup olmadığına baktığı için hata vermedi. Sonuç olarak seed’ler donanım RNG’si yerine MicroPython’un yedek yazılım üreteciyle üretildi.
Block’un mühendislik ekibinin analizine göre bu yedek üretecin başlangıç değeri; cihazın kimlik numarası, bir zamanlayıcı sayacı ve saat gibi büyük ölçüde tahmin edilebilir değerlerden geliyordu. Coinkite’ın kendi tahminine göre gerçek rastgelelik eski modellerde yaklaşık 40 bite, yenilerde yaklaşık 72 bite düştü. 128 bit ile 40 bit arasındaki fark, “imkânsız” ile “bir bilgisayarla denenebilir” arasındaki fark.
Ne oldu?
Saldırganlar cihazlara dokunmadan, olası seed’leri kendi bilgisayarlarında tek tek üretip bakiyesi olan adresleri buldular. TRM Labs’e göre 30 Temmuz’dan itibaren birkaç dalga hâlinde 5.200’den fazla adresten yaklaşık 1.816 BTC (yaklaşık 116 milyon dolar) çekildi. Coinkite ertesi gün düzeltilmiş yazılımları yayınladı.
Önemli nokta şu: Yazılımı güncellemek eski seed’i düzeltmez. Güncelleme sadece bundan sonra üretilecek seed’lerin sağlam olmasını sağlar. Coinkite’ın önerisi, güncelledikten sonra yeni bir seed üretip parayı oraya taşımak.
Coinkite’a göre seed’i üretirken en az 50 zar atışı eklemiş olanlar ya da güçlü bir BIP-39 parolası (passphrase) kullananlar bu açıktan etkilenmedi. Çünkü onlar rastgeleliği cihaza bırakmamıştı.
Yazılımcı olarak ne öğreniyoruz?
- Rastgeleliği test etmek zordur. Zayıf bir üreteç de “rastgele görünen” sayılar üretir. Hiçbir test kırmızıya dönmez.
- Derleme ayarları da koddur. Bir makronun tanımlı olup olmaması ile değerinin ne olduğu farklı şeyler. Bu tür kontroller sessizce yanlış yola sapabilir.
- Tek bir kaynağa güvenme. Birden fazla entropi kaynağını birleştirmek (burada zar atmak gibi), birinin bozulmasına karşı sigorta işlevi görür.
Düşün
- Kodunda bir güvenlik özelliğinin gerçekten çalıştığını nasıl kanıtlardın, sadece “hata vermiyor” demek yeterli mi?
- Kritik bir işi tamamen bir cihaza ya da kütüphaneye bırakmak ne zaman mantıklı, ne zaman değil?