AES Encryption with IV Key Strength
5 min read

AES Encryption with IV Key Strength

AES ile şifreleme konusunda bazen IV kullanmadan sadece key ile ilgili datayı şifreleriz. Bu durumda sabit algoritmada bir şifre türü ortaya çıkar.
AES Encryption with IV Key Strength

Merhaba,

AES ile şifreleme konusunda bazen IV kullanmadan sadece key ile ilgili datayı şifreleriz. Bu durumda sabit algoritmada bir şifre türü ortaya çıkar. Bilindiği üzere IV key'ini public olarak görebiliriz. Hem bu key'i kullanıp hem de kendi algoritmamız ile aynı datayı farklı çıktılar ile elde edebiliriz. Böylelikle aynı data farklı datalar gibi görünür ve izlenme olasılığı minimal dereceye iner. İlk olarak baştan terimlerin ne olduğunu inceleyelim.

AES Şifreleme Nedir?

AES (Advanced Encryption Standard; Gelişmiş Şifreleme Standardı), elektronik verinin şifrelenmesi için sunulan bir standarttır. Amerikan hükûmeti tarafından kabul edilen AES, uluslararası alanda da defacto şifreleme (kripto) standardı olarak kullanılmaktadır. DES'in (Data Encryption Standard - Veri Şifreleme Standardı) yerini almıştır. AES ile tanımlanan şifreleme algoritması, hem şifreleme hem de şifreli metni çözmede kullanılan anahtarların birbiriyle ilişkili olduğu, simetrik-anahtarlı bir algoritmadır. AES için şifreleme ve şifre çözme anahtarları aynıdır.
AES çevrimindeki dört adımdan biri olan Bayt değiştirme işlemi

AES şifrelemeyi bir anahtar-kilit yapısı olarak düşünebilirsiniz. Anahtar bilinmediği sürece o kapıyı açmanın mümkün olmadığı görüşü ile oluşturulmuştur. Sizin bir keyiniz vardır.  Bu key ile ilgili datamızı şifrelemiş oluruz. Bununla birlikte çözmek istersek yine aynı key ile çözüme kavuşuruz. Algoritmanın genel yapısını özetlemek gerekirsek;

  • AES 128, 192, 256 bit anahtarlardan oluşabilir.
  • AES 4x4 sütun - bayt matrisi üzerinde çalışır.
  • Algoritma özdeş dönüşüm çevrimleri bulunur.
  • Her çevrim, son çevrim hariç, dört adımdan oluşur.
  • Şifreyi decrypt etmek için çevrimler ters sıra ile uygulanır.
  • Çevrimlerin tekrar sayıları 128, 192 ve 256 bitten oluşur.
  • Sıralamaları ise 10, 12 ve 14'tür.

Algoritmanın adımlarını genel olarak sıralamak gerekirse;

  • Bayt Değiştir (SubBytes)
  • Satır Kaydır (ShiftRows)
  • Sütun Karıştır (MixColumn)
  • Anahtar Ekle (AddRoundKey)

MixColumn adımında Wikipedia'da bulunduğu üzere bir işlem söz konusudur;

Bu adımda her sütundaki dört bayt değeri tersi olan doğrusal bir dönüşüm kullanılarak birbirleriyle karıştırılır. SütunKarıştır fonksiyonu 4 bayt girdi alıp 4 bayt çıktı verir ve girdideki her baytın çıktıdaki her bayt değerini etkilemesini sağlar. SütunKarıştır işlemi, her sütunun sabit bir matrisle çarpılması işleminden oluşur. Bu sabit matris aşağıda verilmiştir:
Matris çarpması işlemi sonlu cisim GF (28) üzerinde yapılmaktadır. Her bayt bu sonlu cisim üzerinde bir polinom tanımlayacak şekilde, mod x4+1'de c(x) = 0x03 · x3 + x2 + x + 0x02 polinomu ile çarpılır. SütunKarıştır adımındaki sabit matris bir MDS matristir ve SatırKaydır adımı ile birlikte şifrede karmaşıklık (diffusion) sağlar.

AES konusunda fikir sahibi olduğumuzu düşünüyorum. Bundan sonraki süreç ise ilgili anahtarı dışardan izlemini engellemeye çalışmak. Örneklemek gerekirsem;

A diye bir datamızın var olduğunuz düşünelim. ABC keyi ile bu datayı şifreledik diyelim. Sonuç: xDsAsDDvX çıktığını varsayarsak her a datası şifrelendiğinde aynı sonuç çıkacak ve bu durumda giden datanın aynı data olduğu yorumu yapılacaktır. İşin içine IV Key eklesiniz bile 1 adet sunucu ve 1 adet istemcinin olduğunu düşünün. Sunucunun bildiği IV key ile istemcinin bildiği IV key değeri ile şifreleyip, iletişim sağlanabilir fakat IV key sabit olacağı için yine yorumlanabilir. Burada bu makalenin asıl amacı olan IV keyi ilgili dataya farklı bir algoritma ile ekleyip, datayı göndermek.

Yazımızın en başında söylediğim üzere IV key aslında public bir değerdir. Bir başkası tarafından bilinmesi şifreyi çözümlemeye yetmeyecektir çünkü asıl şifrelemede kullanılan key'e ihtiyacımız vardır. Bu durumda bu avantajı kullanıp sürekli aynı datayı farklı çıktılar ile elde edebiliriz. Başlayalım;

var crypto = require('crypto');
var iv = 'CkbKPAH8xb6XeHWK';
var key = 'NzuQSL9XLVw2StmJpZ6r5FyQphCL5ABF';
var data = 'halilhanbadem.dev';

var encdata = crypto.createCipheriv('aes-256-cbc', key, iv);
var encsaltdata = encdata.update(data, 'utf8', 'hex')
encsaltdata += encdata.final('hex');
encsaltdata = Buffer.from(encsaltdata).toString('base64');

console.log("Şifre: ", encsaltdata);

encsaltdata = Buffer.from(encsaltdata, 'base64').toString('utf8');
var decdata = crypto.createDecipheriv('aes-256-cbc', key, iv);
var decsaltdata = decdata.update(encsaltdata, 'hex', 'utf8');
decsaltdata += decdata.final('utf8');


console.log("Çözümlenmiş data: ", decsaltdata);

bu ilgili kodda dikkat ederseniz belirli bir iv key, key ve data ile işlemler yapılıyor. Konsol çıktımız ise;

Şifre:  YmFhZWVlZWQ4OGMzZDA1ZDcxZDRkNDEzYzE5OWQzMGQxODI3YTJhZDY4ZmJjZjA2ODBkNGQ5YjIzY2I2ZGEwNQ==
index.js:11
Çözümlenmiş data:  halilhanbadem.dev
index.js:19

Şeklinde geliyor.

Burada ufak bir değişiklik ile iv key değerimizi sürekli random hale getirip aynı zamanda çözümleyebileceğiz.

function GetRandomIV(length) {
    var result           = '';
    var characters       = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    var charactersLength = characters.length;
    for ( var i = 0; i < length; i++ ) {
      result += characters.charAt(Math.floor(Math.random() * 
 charactersLength));
   }
   return result;
}


var crypto = require('crypto');
var iv = GetRandomIV(16);
var key = 'NzuQSL9XLVw2StmJpZ6r5FyQphCL5ABF';
var data = 'halilhanbadem.dev';

var encdata = crypto.createCipheriv('aes-256-cbc', key, iv);
var encsaltdata = encdata.update(data, 'utf8', 'hex')
encsaltdata += encdata.final('hex');
encsaltdata = Buffer.from(encsaltdata).toString('base64') + "." + iv;

console.log("Şifre: ", encsaltdata);

var sifrelidata = encsaltdata.split('.')[0];
var sifredengelendata = encsaltdata.split('.')[1];
encsaltdata = Buffer.from(sifrelidata, 'base64').toString('utf8');
var decdata = crypto.createDecipheriv('aes-256-cbc', key, sifredengelendata);
var decsaltdata = decdata.update(encsaltdata, 'hex', 'utf8');
decsaltdata += decdata.final('utf8');


console.log("Çözümlenmiş data: ", decsaltdata);

Çıktı:

Şifre:  NDE4MjA5YjhhNmU0YWZkMzczOWQ1OWZmOTE1OTgxNDIyZDI2YmE4MjUxNDM2NGEwMGU1Mjc2NzM2ZmVmNDQ3Yw==.cz21qdt7nZnDBgCd
index.js:23
Çözümlenmiş data:  halilhanbadem.dev
index.js:33

şimdi burada her data farklı çıktı verir çünkü GetRandomIV fonksiyonu bize her istekte farklı bir iv oluşturur ve data çıktısını o şekilde tamamlar. Şifreyi decrypt ederken statik iv yerine ilgili şifredeki (noktadan sonraki kısmı) kısmı dinamik şekilde alıp şifre çözümlendi. Burada IV key çok belli oluyor. Siz daha kompleks bir karıştırma ile daha iyi bir çözüm sağlayabilirsiniz.

yukarıdaki açıklamanın görselleştirilmiş hali.

Anlatım biraz kısa kalmış olabilir. Daha detaylı bir açıklama ile 2. yazıyı da ekleyeceğim.

Not: IV Key'leri `crypto.randomBytes` fonksiyonu ile oluşturmanız ve hashlemeniz daha sağlıklı olur.

Kaynakça:

AES - Vikipedi

Sağlıcakla kalın!