Swift ile Diffie-Helman Anahtar Değişimi (Openssl)

Diffie-Helman, açık bir ağ üzerinde ortak gizli bir anahtar üretmeye yarayan güvenli bir değişim methodudur. Bu yöntem kullanılarak üretilen bir simetrik anahtar bu açık ağda güvenli iletişimi sağlar. Anahtar simetrik olduğundan bir taraf göndereceği mesajı onunla gizlerken diğer tarafta onu aynı anahtarı kullanarak açabilir. Diffie-Helman’ı için verilen en iyi örnek renkler ile anlatılandır:

Aslında bu işlem matematiksel olarak logaritmik yöntemle yapılır. Her iki tarafta açık olan p ve g, bir de gizli a ve b – a bir tarafta, b diğer tarafta olacak şekilde – değerleri vardır vardır. Bu değerlerden bir A değeri hesaplanıp karşı tarafa gönderilir (g^a mod p = A). Karşı tarafta aynı işlemle bir B değeri hesaplayıp karşı tarafa gönderir. İki taraf da kendi gizli anahtarları ve karşı tarafın gönderdiği değerle (B^a mod p = s ve A^b mod p = s) ortak gizli s anahtarını elde ederler.

Bu şifreleme tekniğinin çözülememesi p’nin yeterince büyük olmasına bağlı. Bu sayılar için belirli standartlar mevcut hatta bunun için RFC dökümanları mevcut ( ben örnek olarak en son yayınlanan RFC 5114‘ü referans alacağım).

Olayın iOS swift tarafında da bir kaç kütüphane mevcut fakat p ve g değerlerini dışarıdan alan veya benim kullanacağım değerleri kullananı mevcut değildi. Bunun için OpenSSL kütüphanesini kullanan wrapper class yazdım. Ayrıca OpenSSL’in son versiyonunda benim kullanacağım değerler hazır bir fonksiyon ile verilmişti.

OpenSSL’in projeye dahil etmenin en güzel yolu CocoaPods:

 
 
  1. pod 'OpenSSL-iOS', '~> 1.0.204'

 

Kütüphane seçerken öyle rastgele seçmeyin direk openssl’in yayınladığını bulun ki yazdığım öyle olan.

Temel olarak OpenSSL kütüphanesinden 3 modul bize lazım olacak

 
 
  1. import OpenSSL.bn  //BIGNUM
  2. import OpenSSL.dh  //DIFFIE-HELMAN
  3. import OpenSSL.ossl_typ //tip atamaları

 

İlk olarak diffie-helman context’i mizi yaratalım. Ki bu bize public ve private key üretir:

 
 
  1. self.dh = DH_get_2048_256()  //bahsettiğim fonksiyon.
  2. DH_generate_key(dh)
  3. self.dhPubKey = dh.memory.pub_key
  4. self.dhPriKey = dh.memory.priv_key

 

Sıra hex string şeklinde gelen karşı tarafın public key’i ile ortak gizli anahtarı üretmeye geldi:

 
 
func getCommonKey(peerPubKey:String) throws-> [UInt8]{
        //Generating common key
        let peerPubStr = peerPubKey  //referans atıyacağımız için local değişkene atıyoruz
        var pubBIGNUM = BN_new()
        BN_hex2bn(&pubBIGNUM, peerPubStr) //hex'ten bignum'a dönüştürüyoruz
        
        var commonKeyArr = [UInt8](count: 256, repeatedValue: 0) //256 byte'lık ortak anahtarımız olacak onu oluşturuyoruz
        let status = DH_compute_key(&commonKeyArr, pubBIGNUM, self.dh) //Hesaplamayı yapıp array'e atıyoruz
        if(status < 0){
            throw DHError.DHGeneration("Calculation error for DH parameter, status: \(status.description)")
        }
        
//ortak anahtarımız byte-array şeklinde dönüyor
        return commonKeyArr 
    }

Burada yaptığımız temel olarak karşı tarafın ürettiği B değerini alıp kendi context’imize sokup ortak anahtarı bulmaktı.

Kodları daha düzenli bir şekilde bir cococapods haline getirdim. Oradan kendi projenize indirebilirsiniz:

 
 
  1. pod "GioSwKriptor"

 

Katkıda bulunmak istiyorsanız, github linki: GioSwKriptor (unit testi yazmayı unutmayın!)

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir