Şifrelemeyi SQL veritabanlarıyla kullanma

Adobe AIR 1.5 ve üstü

Tüm Adobe AIR uygulamaları aynı yerel veritabanı motorunu paylaşır. Sonuç olarak, tüm AIR uygulamaları şifrelenmemiş bir veritabanı dosyasına bağlanabilir, bu dosyadan okuyabilir ve bu dosyaya yazabilir. Adobe AIR 1.5'ten başlayarak, AIR şifreli veritabanı dosyaları oluşturma ve bu dosyalara bağlanma özelliğini içerir. Veritabanına bağlanmak için şifreli bir veritabanı kullandığınızda, uygulama doğru şifreleme anahtarını sağlamalıdır. Yanlış şifreleme anahtarı sağlandığında (veya anahtar sağlanmadığında), uygulama veritabanına bağlanamaz. Sonuç olarak, uygulama verileri veritabanından okuyamaz, veritabanına veri yazamaz veya verileri değiştiremez.

Şifreli bir veritabanı kullanmak için, veritabanını şifreli bir veritabanı olarak oluşturmalısınız. Var olan şifreli bir veritabanıyla, veritabanına bağlantı açabilirsiniz. Ayrıca, şifreli bir veritabanının şifreleme anahtarını değiştirebilirsiniz. Şifreli veritabanları oluşturma ve bu veritabanlarına bağlanmanın dışında, şifreli bir veritabanıyla çalışma teknikleri, şifrelenmemiş bir veritabanıyla çalışma tekniklerinin aynısıdır. Özellikle, veritabanının şifreli olup olmamasına bakılmaksızın, SQL ifadeleri yürütme teknikleri aynıdır.

Yerel SQL veritabanları için kullanımlar

Şifreleme, veritabanında saklanan bilgiye erişimi sınırlamak istediğinizde kullanışlı bir yoldur. Adobe AIR'in veritabanı şifreleme işlevleri farklı amaçlar için kullanılabilir. Şifreli bir veritabanı kullanmak isteyebileceğiniz durumlara ilişkin örnekler aşağıdadır:

  • Bir sunucudan indirilen özel uygulama verilerinin salt okunur önbelleği

  • Bir sunucuyla senkronize edilen özel veriler için yerel bir uygulama deposu (sunucuya veri gönderilir ve sunucudan veri yüklenir)

  • Uygulama tarafından oluşturulan ve düzenlenen belgeler için dosya formatı olarak kullanılan şifreli dosyalar. Dosyalar bir kullanıcıya özgü olabilir veya uygulamanın tüm kullanıcıları tarafından paylaşılmak üzere tasarlanmış olabilir.

  • Yerel SQL veritabanları için kullanımlar bölümünde açıklananlar gibi bilgisayara veya veritabanı dosyalarına erişimi olan insanlardan saklı tutulması gereken diğer yerel veri deposu kullanımları.

Şifreli bir veritabanı kullanmak istemenizin nedenini anlamak, uygulamanızı nasıl yapılandıracağınıza karar vermenize yardımcı olur. Özellikle, uygulamanızın veritabanı için şifreleme anahtarını nasıl oluşturacağını, alacağını veya depolayacağını etkileyebilir. Dikkate alınması gereken bu konular hakkında daha fazla bilgi için bkz. Şifrelemeyi veritabanıyla kullanmak için dikkate alınması gerekenler .

Şifreli veritabanı dışında, kritik verilerin gizli kalmasını sağlamada kullanılan alternatif bir mekanizma, şifrelenmiş yerel depo .'dur. Şifrelenmiş yerel depoyla, String anahtarı kullanarak ByteArray değeri saklarsınız. Yalnızca değeri saklayan AIR uygulaması buna erişebilir ve yalnızca değerin saklandığı bilgisayarda erişebilir. Şifreli yerel depoyla, kendi şifreleme anahtarınızı oluşturmanız gerekmez. Bu nedenle, şifreli yerel depo bir ByteArray içinde kolayca kodlanabilen tek bir değer veya değerler kümesini kolayca saklamak için en uygun yoldur. Şifreli veritabanı, yapılandırılmış veri depolama ve sorgulamanın amaçlandığı daha büyük veri kümeleri için daha uygundur. Şifreli yerel depo kullanımı hakkında daha fazla bilgi için, bkz. Şifrelenmiş yerel depolama .

Şifreli veritabanı oluşturma

Şifreli bir veritabanı kullanmak için, veritabanı dosyası oluşturulduğu sırada şifrelenmelidir. Veritabanı bir kez şifrelenmemiş olarak oluşturulduğunda, sonradan şifrelenemez. Benzer şekilde, şifreli bir veritabanının daha sonra şifresi kaldırılamaz. Ayrıca, şifreli bir veritabanının şifreleme anahtarını değiştirebilirsiniz. Ayrıntılar için bkz. Veritabanının şifreleme anahtarını değiştirme . Şifrelenmemiş bir veritabanınız varsa ve veritabanı şifrelemeyi kullanmak istiyorsanız, yeni ve şifreli bir veritabanı oluşturabilir ve var olan tablo yapısını ve verileri yeni veritabanına kopyalayabilirsiniz.

Şifreli bir veritabanı oluşturmak, Veritabanı oluşturma bölümünde anlatıldığı gibi, şifrelenmemiş bir veritabanı oluşturmakla hemen hemen aynıdır. Önce veritabanına bağlantıyı temsil eden bir SQLConnection örneği oluşturuyorsunuz. Henüz var olmayan bir dosya için veritabanı konumunu belirterek, SQLConnection nesnesinin open() yöntemini veya openAsync() yöntemini çağırma yoluyla veritabanını oluşturabilirsiniz. Şifreli veritabanı oluşturmanın tek farkı, encryptionKey parametresi için ( open() yönteminin beşinci parametresi ve openAsync() yönteminin altıncı parametresi) bir değer sağlamanız gerekmesidir.

Geçerli bir encryptionKey parametre değeri, tam olarak 16 bayt içeren bir ByteArray nesnesidir.

Aşağıdaki örneklerde şifrelenmiş veritabanı oluşturma gösterilmiştir. Basitleştirmek için, bu örnekte şifreleme anahtarı uygulama kodunda sabit olarak kodlanmıştır. Ancak, bu teknik güvenli olmadığı için kesinlikle önerilmez.

var conn:SQLConnection = new SQLConnection(); 
     
var encryptionKey:ByteArray = new ByteArray(); 
encryptionKey.writeUTFBytes("Some16ByteString"); // This technique is not secure! 
     
// Create an encrypted database in asynchronous mode 
conn.openAsync(dbFile, SQLMode.CREATE, null, false, 1024, encryptionKey); 
     
// Create an encrypted database in synchronous mode 
conn.open(dbFile, SQLMode.CREATE, false, 1024, encryptionKey);

Şifreleme anahtarı oluşturmak için önerilen bir yolu gösteren örnek için bkz. Örnek: Şifreleme anahtarı oluşturma ve kullanma .

Şifreli bir veritabanına bağlanma

Şifreli veritabanı oluşturma gibi, şifreli bir veritabanına bağlantı açma yordamı da şifrelenmemiş bir veritabanına bağlanmaya benzer. Bu yordam, Veritabanına bağlanma bölümünde daha ayrıntılı biçimde açıklanmıştır. Senkronize yürütme modunda bir bağlantı açmak için open() yöntemini veya senkronize olmayan yürütme modunda bağlantı açmak için openAsync() yöntemini kullanın. Aradaki tek fark, şifreli bir veritabanını açmak için encryptionKey parametresine ilişkin ( open() yönteminin beşinci parametresi ve openAsync() yönteminin altıncı parametresi) doğru değeri belirtmeniz gerekiyor olmasıdır.

Sağlanan şifreleme anahtarı doğru değilse, bir hata oluşur. open() yöntemi için, SQLError istisnası verilir. SQLConnection nesnesi, openAsync() yöntemi için, error özelliği bir SQLError nesnesi içeren bir SQLErrorEvent gönderir. Her durumda, istisna tarafından oluşturulan SQLError nesnesi errorID özellik değeri 3138'e sahiptir. Bu hata kimliği, “Açılan dosya bir veritabanı dosyası değil” hata mesajına karşılık gelir.

Aşağıdaki örnek, senkronize olmayan yürütme modunda şifreli veritabanı açmayı gösterir. Basitleştirmek için, bu örnekte şifreleme anahtarı uygulama kodunda sabit olarak kodlanmıştır. Ancak, bu teknik güvenli olmadığı için kesinlikle önerilmez.

import flash.data.SQLConnection; 
import flash.data.SQLMode; 
import flash.events.SQLErrorEvent; 
import flash.events.SQLEvent; 
import flash.filesystem.File; 
     
var conn:SQLConnection = new SQLConnection(); 
conn.addEventListener(SQLEvent.OPEN, openHandler); 
conn.addEventListener(SQLErrorEvent.ERROR, errorHandler); 
var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db"); 
     
var encryptionKey:ByteArray = new ByteArray(); 
encryptionKey.writeUTFBytes("Some16ByteString"); // This technique is not secure! 
     
conn.openAsync(dbFile, SQLMode.UPDATE, null, false, 1024, encryptionKey); 
     
function openHandler(event:SQLEvent):void 
{ 
    trace("the database opened successfully"); 
} 
     
function errorHandler(event:SQLErrorEvent):void 
{ 
    if (event.error.errorID == 3138) 
    { 
        trace("Incorrect encryption key"); 
    } 
    else 
    { 
        trace("Error message:", event.error.message); 
        trace("Details:", event.error.details); 
    } 
} 

Aşağıdaki örnek, senkronize yürütme modunda şifreli veritabanı açmayı gösterir. Basitleştirmek için, bu örnekte şifreleme anahtarı uygulama kodunda sabit olarak kodlanmıştır. Ancak, bu teknik güvenli olmadığı için kesinlikle önerilmez.

import flash.data.SQLConnection; 
import flash.data.SQLMode; 
import flash.filesystem.File; 
     
var conn:SQLConnection = new SQLConnection(); 
var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db"); 
     
var encryptionKey:ByteArray = new ByteArray(); 
encryptionKey.writeUTFBytes("Some16ByteString"); // This technique is not secure! 
     
try 
{ 
    conn.open(dbFile, SQLMode.UPDATE, false, 1024, encryptionKey); 
    trace("the database was created successfully"); 
} 
catch (error:SQLError) 
{ 
    if (error.errorID == 3138) 
    { 
        trace("Incorrect encryption key"); 
    } 
    else 
    { 
        trace("Error message:", error.message); 
        trace("Details:", error.details); 
    } 
} 

Şifreleme anahtarı oluşturmak için önerilen bir yolu gösteren örnek için bkz. Örnek: Şifreleme anahtarı oluşturma ve kullanma .

Veritabanının şifreleme anahtarını değiştirme

Veritabanı şifrelendiğinde, veritabanına ilişkin şifreleme anahtarını sonradan değiştirebilirsiniz. Veritabanının şifreleme anahtarını değiştirmek için önce bir SQLConnection örneği oluşturarak ve bunun open() veya openAsync() yöntemini çağırarak veritabanına bağlantı açın. Veritabanına bağlanıldığında, argüman olarak yeni şifreleme anahtarını ileterek reencrypt() yöntemini çağırın.

Çoğu veritabanı işlemi gibi, reencrypt() yönteminin davranışı, veritabanı bağlantısının senkronize veya senkronize olmayan yürütme modunu kullanıyor olmasına göre değişir. Veritabanına bağlanmak için open() yöntemini kullanırsanız reencrypt() işlemi senkronize olarak çalışır. İşlem tamamlandığında, yürütme sonraki kod satırıyla devam eder:

var newKey:ByteArray = new ByteArray(); 
// ... generate the new key and store it in newKey 
conn.reencrypt(newKey);

Diğer yandan, veritabanı bağlantısı openAsync() yöntemi kullanılarak açıldıysa, reencrypt() işlemi senkronize olmayan modda çalışır. reencrypt() yönteminin çağrılması, yeniden şifreleme işlemini başlatır. İşlem tamamlandığında, SQLConnection nesnesi bir reencrypt olayı gönderir. Yeniden şifrelemenin tamamlandığını belirlemek için bir olay dinleyicisi kullanabilirsiniz:

var newKey:ByteArray = new ByteArray(); 
// ... generate the new key and store it in newKey 
     
conn.addEventListener(SQLEvent.REENCRYPT, reencryptHandler); 
     
conn.reencrypt(newKey); 
     
function reencryptHandler(event:SQLEvent):void 
{ 
    // save the fact that the key changed 
}

reencrypt() işlemi, kendi işlemi içinde çalışır. İşlem kesintiye uğradığında veya başarısız olduğunda (örneğin, uygulama işlem tamamlanmadan kapatıldığında) işlem geri alınır. Bu durumda, ilk şifreleme anahtarı veritabanının şifreleme anahtarı olarak kalır.

reencrypt() yöntemi, veritabanından şifrelemeyi kaldırmak için kullanılamaz. reencrypt() yöntemine null değerinin veya 16 bayt olmayan bir ByteArray değerinin iletilmesi hatayla sonuçlanır.

Şifrelemeyi veritabanıyla kullanmak için dikkate alınması gerekenler

Yerel SQL veritabanları için kullanımlar bölümü, şifreli veritabanı kullanmak isteyebileceğiniz çeşitli durumları gösterir. Farklı uygulamaların kullanım senaryolarının (bunlar ve diğer senaryolar dahil) farklı gizlilik gereksinimleri olduğu açıktır. Uygulamanızda şifreleme kullanımını yapılandırma biçiminiz, bir veritabanındaki verilerin ne kadar özel olduğunu denetlemenizin önemli bir parçasıdır. Örneğin, şifreli veritabanını kişisel verilerinizi aynı bilgisayarı kullanan diğer kullanıcılardan bile saklı tutmak için kullanıyorsanız, her kullanıcının veritabanı kendi şifreleme anahtarını gerektirir. En yüksek düzeyde güvenlik için, uygulamanız kullanıcı tarafından girilen paroladan anahtar oluşturabilir. Şifreleme anahtarını parolaya dayandırmak, başka bir kişi kullanıcının bilgisayardaki hesabına erişmeyi başarsa bile, verilere erişememesini sağlar. Güvenlik spektrumunun diğer ucunda, bir veritabanı dosyasının uygulamanızın tüm kullanıcıları için okunabilir olmasını, ancak diğer uygulamaların bu dosyaya erişememesini istiyorsunuz. Bu durumda, uygulamanın yüklenmiş her kopyasının, paylaşımlı bir şifreleme anahtarına erişimi olması gerekir.

Uygulamanızı ve özellikle şifreleme anahtarının oluşturulduğu tekniği uygulama verileriniz için kullanmak istediğiniz gizlilik düzeyine göre tasarlayabilirsiniz. Aşağıdaki liste, farklı veri gizliliği düzeyleri için tasarım önerileri sunar:

  • Veritabanını herhangi bir bilgisayardaki uygulamaya erişimi olan tüm kullanıcılar için erişilebilir kılmak için uygulamanın tüm örnekleri tarafından kullanılabilen tek bir anahtar kullanın. Örneğin, uygulama ilk kez çalıştırıldığında, SSL gibi güvenli bir protokol kullanarak bir sunucudan paylaşımlı şifreleme anahtarını indirebilir. Anahtarı gelecekte kullanmak üzere şifreli yerel depoya kaydedebilir. Alternatif olarak, bilgisayardaki her kullanıcıya ilişkin verileri şifreleyin ve verileri taşınabilir kılmak için sunucu gibi uzak bir veri deposuyla senkronize edin.

  • Veritabanını herhangi bir bilgisayardaki tek bir kullanıcı tarafından erişilebilir kılmak için, şifreleme anahtarını bir kullanıcı sırrından (parola gibi) oluşturun. Anahtarı oluşturmak için belirli bir bilgisayara bağlı olan herhangi bir değeri (şifreli yerel depoda saklanan bir değer gibi) kullanmayın. Alternatif olarak, bilgisayardaki her kullanıcıya ilişkin verileri şifreleyin ve verileri taşınabilir kılmak için sunucu gibi uzak bir veri deposuyla senkronize edin.

  • Veritabanını tek bir bilgisayardaki tek bir kişi tarafından erişilebilir kılmak için, anahtarı bir paroladan ve oluşturulmuş bir salttan yaratın. Bu tekniğe ilişkin bir örnek için bkz. Örnek: Şifreleme anahtarı oluşturma ve kullanma .

Bir uygulamayı şifreli bir veritabanı kullanmak üzere tasarlarken göz önüne alınması gereken diğer güvenlik konuları şunlardır:

  • Bir sistem her zaman en zayıf noktası kadar güvenlidir. Şifreleme anahtarı kullanmak için kullanıcı tarafından girilen bir parolayı kullanıyorsanız, parolalarda minimum uzunluk ve karmaşıklık sınırlamaları uygulamayı göz önünde bulundurun. Yalnızca temel karakterleri kullanan kısa bir parola, kolayca tahmin edilebilir.

  • AIR uygulamasının kaynak kodu, kullanıcının bilgisayarında düz metinde (HTML içeriği için) veya derlemesi kolayca açılabilir bir ikili formatta (SWF içeriği için) saklanır. Kaynak kod erişilebilir olduğundan, hatırlanması gereken iki nokta şöyledir:

    • Şifreleme anahtarınızı kaynak kodunuzda asla sabit olarak kodlamayın

    • Şifreleme anahtarını oluşturmak için kullanılan tekniğin (rastgele karakter oluşturucu veya belirli bir karma algoritma) bir saldırgan tarafından kolayca çözülebileceğini her zaman göz önünde bulundurun

  • AIR veritabanı şifreleme CBC-MAC (CCM) moduyla Counter içeren Gelişmiş Şifreleme Standardı'nı (AES) kullanır. Bu şifreleme, güvenli olmak için bir salt değeriyle birleştirilen kullanıcı tarafından girilmiş bir anahtarı gerektirir. Buna ilişkin bir örnek için bkz. Örnek: Şifreleme anahtarı oluşturma ve kullanma .

  • Veritabanını şifrelemeyi seçtiğinizde, bu veritabanıyla bağlantılı olan veritabanı motoru tarafından kullanılan tüm disk dosyaları şifrelenir. Ancak, veritabanı motoru işlemlerdeki okuma ve yazma süresi performansını artırmak için bazı verileri geçici olarak bellek içi bir önbellekte tutar. Bellekte yerleşik veriler şifrelenmez. Saldırgan AIR uygulaması tarafından kullanılan belleğe erişmeyi örneğin hata ayıklayıcı kullanarak başarırsa, veritabanında açık ve şifrelenmemiş olan veriler kullanılabilir durumda olabilir.

Örnek: Şifreleme anahtarı oluşturma ve kullanma

Bu örnek uygulama, şifreleme anahtarı oluşturma için bir tekniği gösterir. Bu uygulama, kullanıcının verileri için en yüksek düzeyde gizlilik ve güvenlik sağlamak üzere tasarlanmıştır. Kişisel verileri korumanın önemli bir yönü, uygulamanın veritabanına her bağlanmasında kullanıcının parolayı girmesini gerektirmesidir. Sonuç olarak, bu örnekte gösterildiği gibi, bu gizlilik düzeyini gerektiren bir uygulama, veritabanı şifreleme anahtarını hiçbir zaman doğrudan saklamamalıdır.

Uygulama iki bölümden oluşur: Şifreleme anahtarını oluşturan ActionScript sınıfı (EncryptionKeyGenerator sınıfı) ve bu sınıfın nasıl kullanılacağını gösteren temel bir kullanıcı arabirimi. Tam kaynak kodu için bkz. Şifreleme anahtarı oluşturmak için tam örnek kod .

Güvenli bir şifreleme anahtarı elde etmek için EncryptionKeyGenerator sınıfını kullanma

EncryptionKeyGenerator sınıfının nasıl çalıştığının ayrıntılarını anlamak onu uygulamanızda kullanmak için gerekli değildir. Bir sınıfın bir veritabanı için nasıl bir şifreleme anahtarı oluşturduğunun ayrıntılarıyla ilgileniyorsanız, bkz. EncryptionKeyGenerator sınıfını anlama .

EncryptionKeyGenerator sınıfını uygulamanızda kullanmak için bu adımları izleyin:

  1. EncryptionKeyGenerator sınıfını kaynak kodu veya bir derlenmiş SWC olarak indirin. EncryptionKeyGenerator sınıfı açık kaynaklı ActionScript 3.0 çekirdek kütüphanesi (as3corelib) projesine dahildir. Kaynak kod ve belgeleri içeren as3corelib paketini indirebilirsiniz . Ayrıca proje sayfasından SWC veya kaynak kod dosyalarını da indirebilirsiniz.

  2. EncryptionKeyGenerator sınıfına ilişkin kaynak kodu (veya as3corelib SWC) uygulama kaynak kodunuzun onu bulabileceği bir konuma yerleştirin.

  3. Uygulama kaynak kodunuzda, EncryptionKeyGenerator sınıfı için bir import ifadesi ekleyin.

    import com.adobe.air.crypto.EncryptionKeyGenerator;
  4. Kodun veritabanını oluşturduğu veya veritabanına bağlantı açtığı noktadan önce, EncryptionKeyGenerator() yapıcısını çağırarak bir EncryptionKeyGenerator örneği yaratacak kodu ekleyin.

    var keyGenerator:EncryptionKeyGenerator = new EncryptionKeyGenerator();
  5. Kullanıcıdan parola alın:

    var password:String = passwordInput.text; 
     
    if (!keyGenerator.validateStrongPassword(password)) 
    { 
        // display an error message 
        return; 
    }

    EncryptionKeyGenerator örneği, bu parolayı şifreleme anahtarı için temel olarak kullanır. (Sonraki örnekte gösterilmiştir.) EncryptionKeyGenerator örneği, belirli güçlü parola doğrulama gereksinimlerine karşı parolayı test eder. Doğrulama başarısız olursa, bir hata oluşur. Örnek kodun gösterdiği gibi, parolayı daha sonra EncryptionKeyGenerator nesnesinin validateStrongPassword() yöntemini kullanarak kontrol edebilirsiniz. Bu yolla parolanın hatayı önlemek üzere güçlü bir parola olmak için minimum gereksinimleri karşılayıp karşılamadığını belirleyebilirsiniz.

  6. Şifreleme anahtarını paroladan oluşturun:

    var encryptionKey:ByteArray = keyGenerator.getEncryptionKey(password);

    getEncryptionKey() yöntemi, şifreleme anahtarını oluşturur ve döndürür (16 bayt ByteArray). Daha sonra şifreleme anahtarını yeni şifreli veritabanınızı oluşturmak için veya var olan veritabanını açmak için kullanabilirsiniz.

    getEncryptionKey() yöntemi, adım 5'te elde edilen parola olan tek bir gerekli parametre içerir.

    Not: Veriler için güvenlik ve gizliliği en yüksek düzeyde tutmak için, uygulama veritabanına her bağlandığında kullanıcının şifre girmesini gerektirir. Kullanıcı parolasını veya veritabanı şifreleme anahtarını doğrudan saklamayın. Bunu yapmak güvenlik riskleri oluşturur. Bunun yerine, bu örnekte gösterildiği gibi, bir uygulama şifreli bir veritabanı oluştururken veya sonradan bu veritabanına bağlanırken paroladan şifreleme anahtarı türetmek için aynı tekniği kullanmalıdır.

    getEncryptionKey() yöntemi ikinci (isteğe bağlı) bir parametre olan overrideSaltELSKey parametresini de kabul eder. EncryptionKeyGenerator, şifreleme anahtarının parçası olarak kullanılan rastgele bir değer ( salt olarak bilinir) oluşturur. Şifreleme anahtarının yeniden oluşturulabilmesi için, salt değeri AIR uygulamanızın Şifreli Yerel Depo'sunda (ELS) saklanır. Varsayılan olarak, EncryptionKeyGenerator sınıfı ELS anahtarı olarak belirli bir Dize kullanır. Düşük bir ihtimal olsa da, anahtar uygulama tarafından kullanılan başka bir anahtarla çakışabilir. Varsayılan anahtarı kullanmak yerine, kendi ELS anahtarınızı belirlemek isteyebilirsiniz. Bu durumda, burada gösterildiği gibi, ikinci getEncryptionKey() parametresi olarak iletilecek özel bir anahtar belirleyin:

    var customKey:String = "My custom ELS salt key"; 
    var encryptionKey:ByteArray = keyGenerator.getEncryptionKey(password, customKey);
  7. Veritabanı oluşturma veya açma

    Kodunuz getEncryptionKey() yöntemi tarafından döndürülen bir şifreleme anahtarıyla yeni bir şifreli veritabanı oluşturabilir veya var olan şifreli bir veritabanını açmayı deneyebilir. Her iki durumda da, Şifreli veritabanı oluşturma ve Şifreli bir veritabanına bağlanma bölümlerinde açıklandığı gibi SQLConnection sınıfının open() veya openAsync() yöntemini kullanırsınız.

    Bu örnekte, uygulama veritabanını senkronize olmayan yürütme modunda açmak üzere tasarlanmıştır. Kod, uygun olay dinleyicilerini ayarlar ve şifreleme anahtarını son argüman olarak ileterek openAsync() yöntemini çağırır:

    conn.addEventListener(SQLEvent.OPEN, openHandler); 
    conn.addEventListener(SQLErrorEvent.ERROR, openError); 
     
    conn.openAsync(dbFile, SQLMode.CREATE, null, false, 1024, encryptionKey);

    Kod, dinleyici yöntemlerinde olay dinleyicisi kayıtlarını kaldırır. Daha sonra veritabanının oluşturulduğunu, açıldığını veya bir hata oluştuğunu gösteren bir durum mesajı görüntüler. Bu olay işleyicilerinin en önemli bölümü openError() yöntemindedir. Bu yöntemde if ifadesi veritabanının var olup olmadığını (kodun var olan bir veritabanına bağlanmaya çalıştığı anlamına gelir) ve hata kimliği eşleşmelerinin sabit olup olmadığını kontrol eder EncryptionKeyGenerator.ENCRYPTED_DB_PASSWORD_ERROR_ID . Bu koşullardan her ikisi de doğruysa, bu büyük olasılıkla kullanıcının girdiği parolanın yanlış olduğu anlamına gelir. (Belirtilen dosyanın bir veritabanı dosyası olmadığı anlamına da gelebilir.) Hata kimliğini kontrol eden kod aşağıdadır:

    if (!createNewDB && event.error.errorID == EncryptionKeyGenerator.ENCRYPTED_DB_PASSWORD_ERROR_ID) 
    { 
        statusMsg.text = "Incorrect password!"; 
    } 
    else 
    { 
        statusMsg.text = "Error creating or opening database."; 
    }

    Örnek olay dinleyicileri için tam kod için bkz. Şifreleme anahtarı oluşturmak için tam örnek kod .

Şifreleme anahtarı oluşturmak için tam örnek kod

Aşağıdaki, “Şifreleme anahtarı oluşturma ve kullanma” örnek uygulaması için tam koddur. Kod, iki bölümden oluşur.

Örnek, paroladan şifreleme anahtarı oluşturmak için EncryptionKeyGenerator sınıfını kullanır. EncryptionKeyGenerator sınıfı açık kaynaklı ActionScript 3.0 çekirdek kütüphanesi (as3corelib) projesine dahildir. Kaynak kod ve belgeleri içeren as3corelib paketini indirebilirsiniz . Ayrıca proje sayfasından SWC veya kaynak kod dosyalarını da indirebilirsiniz.

Flex örneği

Uygulama MXML dosyası, şifreli bir veritabanına bağlantı oluşturan veya açan basit bir uygulamaya ilişkin kaynak kodunu içerir:

<?xml version="1.0" encoding="utf-8"?> 
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="init();"> 
    <mx:Script> 
        <![CDATA[ 
            import com.adobe.air.crypto.EncryptionKeyGenerator; 
             
            private const dbFileName:String = "encryptedDatabase.db"; 
             
            private var dbFile:File; 
            private var createNewDB:Boolean = true; 
            private var conn:SQLConnection; 
             
            // ------- Event handling ------- 
             
            private function init():void 
            { 
                conn = new SQLConnection(); 
                dbFile = File.applicationStorageDirectory.resolvePath(dbFileName); 
                if (dbFile.exists) 
                { 
                    createNewDB = false; 
                    instructions.text = "Enter your database password to open the encrypted database."; 
                    openButton.label = "Open Database"; 
                } 
            } 
             
            private function openConnection():void 
            { 
                var password:String = passwordInput.text; 
                 
                var keyGenerator:EncryptionKeyGenerator = new EncryptionKeyGenerator(); 
                 
                if (password == null || password.length <= 0) 
                { 
                    statusMsg.text = "Please specify a password."; 
                    return; 
                } 
                 
                if (!keyGenerator.validateStrongPassword(password)) 
                { 
                    statusMsg.text = "The password must be 8-32 characters long. It must contain at least one lowercase letter, at least one uppercase letter, and at least one number or symbol."; 
                    return; 
                } 
                 
                passwordInput.text = ""; 
                passwordInput.enabled = false; 
                openButton.enabled = false; 
                 
                var encryptionKey:ByteArray = keyGenerator.getEncryptionKey(password); 
                 
                conn.addEventListener(SQLEvent.OPEN, openHandler); 
                conn.addEventListener(SQLErrorEvent.ERROR, openError); 
                  
                conn.openAsync(dbFile, SQLMode.CREATE, null, false, 1024, encryptionKey); 
            } 
             
            private function openHandler(event:SQLEvent):void 
            { 
                conn.removeEventListener(SQLEvent.OPEN, openHandler); 
                conn.removeEventListener(SQLErrorEvent.ERROR, openError); 
                  
                statusMsg.setStyle("color", 0x009900); 
                if (createNewDB) 
                { 
                    statusMsg.text = "The encrypted database was created successfully."; 
                } 
                else 
                { 
                    statusMsg.text = "The encrypted database was opened successfully."; 
                } 
            } 
              
            private function openError(event:SQLErrorEvent):void 
            { 
                conn.removeEventListener(SQLEvent.OPEN, openHandler); 
                conn.removeEventListener(SQLErrorEvent.ERROR, openError); 
     
                if (!createNewDB && event.error.errorID == EncryptionKeyGenerator.ENCRYPTED_DB_PASSWORD_ERROR_ID) 
                { 
                    statusMsg.text = "Incorrect password!"; 
                } 
                else 
                { 
                    statusMsg.text = "Error creating or opening database."; 
                } 
            } 
        ]]> 
    </mx:Script> 
    <mx:Text id="instructions" text="Enter a password to create an encrypted database. The next time you open the application, you will need to re-enter the password to open the database again." width="75%" height="65"/> 
    <mx:HBox> 
        <mx:TextInput id="passwordInput" displayAsPassword="true"/> 
        <mx:Button id="openButton" label="Create Database" click="openConnection();"/> 
    </mx:HBox> 
    <mx:Text id="statusMsg" color="#990000" width="75%"/> 
</mx:WindowedApplication>

Flash Professional örneği

Uygulama FLA dosyası, şifreli bir veritabanına bağlantı oluşturan veya açan basit bir uygulamaya ilişkin kaynak kodunu içerir. FLA dosyası, sahnede konumlandırılmış dört bileşen içerir:

Örnek adı

Bileşen türü

Açıklama

instructions

Label

Kullanıcıya verilen talimatları içerir

passwordInput

TextInput

Kullanıcının parolayı girdiği giriş alanı

openButton

Düğme

Kullanıcının parolayı girdikten sonra tıklattığı düğme

statusMsg

Etiket

Durum (başarı veya hata) mesajlarını görüntüler

Uygulamaya ilişkin kod, ana zaman çizelgesinin kare 1'i üzerindeki anahtar karede tanımlanmıştır. Aşağıdaki, uygulamaya ilişkin koddur:

import com.adobe.air.crypto.EncryptionKeyGenerator; 
     
const dbFileName:String = "encryptedDatabase.db"; 
     
var dbFile:File; 
var createNewDB:Boolean = true; 
var conn:SQLConnection; 
     
init(); 
     
// ------- Event handling ------- 
     
function init():void 
{ 
    passwordInput.displayAsPassword = true; 
    openButton.addEventListener(MouseEvent.CLICK, openConnection); 
    statusMsg.setStyle("textFormat", new TextFormat(null, null, 0x990000)); 
     
    conn = new SQLConnection(); 
    dbFile = File.applicationStorageDirectory.resolvePath(dbFileName); 
     
    if (dbFile.exists) 
    { 
        createNewDB = false; 
        instructions.text = "Enter your database password to open the encrypted database."; 
        openButton.label = "Open Database"; 
    } 
    else 
    { 
        instructions.text = "Enter a password to create an encrypted database. The next time you open the application, you will need to re-enter the password to open the database again."; 
        openButton.label = "Create Database"; 
    } 
} 
     
function openConnection(event:MouseEvent):void 
{ 
    var keyGenerator:EncryptionKeyGenerator = new EncryptionKeyGenerator(); 
     
    var password:String = passwordInput.text; 
     
    if (password == null || password.length <= 0) 
    { 
        statusMsg.text = "Please specify a password."; 
        return; 
    } 
     
    if (!keyGenerator.validateStrongPassword(password)) 
    { 
        statusMsg.text = "The password must be 8-32 characters long. It must contain at least one lowercase letter, at least one uppercase letter, and at least one number or symbol."; 
        return; 
    } 
     
    passwordInput.text = ""; 
    passwordInput.enabled = false; 
    openButton.enabled = false; 
     
    var encryptionKey:ByteArray = keyGenerator.getEncryptionKey(password); 
     
    conn.addEventListener(SQLEvent.OPEN, openHandler); 
    conn.addEventListener(SQLErrorEvent.ERROR, openError); 
     
    conn.openAsync(dbFile, SQLMode.CREATE, null, false, 1024, encryptionKey); 
} 
     
function openHandler(event:SQLEvent):void 
{ 
    conn.removeEventListener(SQLEvent.OPEN, openHandler); 
    conn.removeEventListener(SQLErrorEvent.ERROR, openError); 
     
    statusMsg.setStyle("textFormat", new TextFormat(null, null, 0x009900)); 
    if (createNewDB) 
    { 
        statusMsg.text = "The encrypted database was created successfully."; 
    } 
    else 
    { 
        statusMsg.text = "The encrypted database was opened successfully."; 
    } 
} 
 
function openError(event:SQLErrorEvent):void 
{ 
    conn.removeEventListener(SQLEvent.OPEN, openHandler); 
    conn.removeEventListener(SQLErrorEvent.ERROR, openError); 
     
    if (!createNewDB && event.error.errorID == EncryptionKeyGenerator.ENCRYPTED_DB_PASSWORD_ERROR_ID) 
    { 
        statusMsg.text = "Incorrect password!"; 
    } 
    else 
    { 
        statusMsg.text = "Error creating or opening database."; 
    } 
}

EncryptionKeyGenerator sınıfını anlama

EncryptionKeyGenerator sınıfını uygulama veritabanınıza ilişkin güvenli bir şifreleme anahtarı oluşturmak üzere kullanmak için bu sınıfın iç çalışma yapısını anlamak gerekli değildir. Sınıfı kullanma işlemleri Güvenli bir şifreleme anahtarı elde etmek için EncryptionKeyGenerator sınıfını kullanma bölümünde anlatılmıştır. Ancak, bu sınıfın kullandığı teknikleri anlamayı önemli görüyor olabilirsiniz. Örneğin, sınıfı uyarlamak veya farklı bir veri gizlilik düzeyi istenen durumlar için sınıfın tekniklerinden bazılarını birleştirmek isteyebilirsiniz.

EncryptionKeyGenerator sınıfı açık kaynaklı ActionScript 3.0 çekirdek kütüphanesi (as3corelib) projesine dahildir. Kaynak kodu ve belgeler dahil the as3corelib paketini indirebilirsiniz .Ayrıca proje sitesinde kaynak kodunu görüntüleyebilir ve açıklamalarla birlikte takip etmek üzere indirebilirsiniz.

Kod bir EncryptionKeyGenerator örneği oluşturduğunda ve bu örneğin getEncryptionKey() yöntemini çağırdığında, yalnızca hak sahibi kullanıcının verilere erişebilmesini sağlamak için bazı adımlar atılır. Veritabanı oluşturulmadan önce kullanıcı tarafından girilen paroladan bir şifreleme anahtarı oluşturma işlemi, veritabanını açmak için şifreleme anahtarını yeniden oluşturma işlemiyle aynıdır.

Güçlü bir parola elde edin ve doğrulayın

Kod getEncryptionKey() yöntemini çağırdığında, parametre olarak bir parola sunar. Parola, şifreleme anahtarı için temel olarak kullanılır. Bu tasarım, yalnızca kullanıcının bildiği bir bilgiyi kullanarak yalnızca parolayı bilen kullanıcının veritabanındaki verilere ulaşabilmesini sağlar. Bir saldırgan kullanıcının bilgisayardaki hesabına erişse bile, parolayı bilmeden veritabanına giremez. Maksimum güvenlik için, uygulama parolayı hiçbir zaman saklamaz.

Bir uygulamanın kodu bir EncryptionKeyGenerator örneği oluşturur ve argüman olarak kullanıcı tarafından girilen bir şifreyi geçerek onun getEncryptionKey() yöntemini çağırır (bu örnekte password değişkeni):

var keyGenerator:EncryptionKeyGenerator = new EncryptionKeyGenerator(); 
var encryptionKey:ByteArray = keyGenerator.getEncryptionKey(password);

getEncryptionKey() yöntemi çağrıldığında EncryptionKeyGenerator sınıfının attığı ilk adım, parola güvenlik düzeyi gereksinimlerini karşıladığından emin olmak için kullanıcı tarafından girilen parolayı kontrol etmektir. EncryptionKeyGenerator sınıfı bir şifrenin 8 - 32 karakter arasında olmasını gerektirir. Şifre, büyük ve küçük harflerin karışımından ve en az bir sayı veya sembol karakterinden oluşmalıdır.

Bu modeli kontrol eden yaygın ifade, STRONG_PASSWORD_PATTERN adlı bir sabit olarak tanımlanır:

private static const STRONG_PASSWORD_PATTERN:RegExp = /(?=^.{8,32}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/;

Parolayı kontrol eden kod, EncryptionKeyGenerator sınıfının validateStrongPassword() yöntemindedir. Kod şöyledir:

public function vaidateStrongPassword(password:String):Boolean 
{ 
    if (password == null || password.length <= 0) 
    { 
        return false; 
    } 
     
    return STRONG_PASSWORD_PATTERN.test(password)) 
}

Dahili olarak, getEncryptionKey() yöntemi EncryptionKeyGenerator sınıfının validateStrongPassword() yöntemini çağırır ve parola geçerli değilse bir istisna atar. validateStrongPassword() yöntemi, genel bir yöntemdir ve böylece uygulama kodu, hata oluşmasını önlemek için getEncryptionKey() yöntemini çağırmadan parolayı kontrol edebilir.

Parolayı 256 bit olarak genişletin

İşlemin sonraki aşamalarında, parola 256 bit uzunluğunda olmalıdır. Her kullanıcının tam olarak 256 bit (32 karakter) uzunluğunda olan bir parola girmesini gerektirmek yerine, kod parola karakterlerini yineleyerek daha uzun bir parola oluşturur.

getEncryptionKey() yöntemi, uzun parola oluşturma görevini gerçekleştirmek için concatenatePassword() yöntemini çağırır.

var concatenatedPassword:String = concatenatePassword(password);

Aşağıdaki, concatenatePassword() yöntemine ilişkin koddur:

private function concatenatePassword(pwd:String):String 
{ 
    var len:int = pwd.length; 
    var targetLength:int = 32; 
     
    if (len == targetLength) 
    { 
        return pwd; 
    } 
     
    var repetitions:int = Math.floor(targetLength / len); 
    var excess:int = targetLength % len; 
     
    var result:String = ""; 
     
    for (var i:uint = 0; i < repetitions; i++) 
    { 
        result += pwd; 
    } 
     
    result += pwd.substr(0, excess); 
     
    return result; 
}

Parola 256 bitten kısa olduğunda, kod parolayı 256 bit yapmak için kendisiyle bitiştirir. Uzunluk tam olarak oluşmuyorsa, son yineleme parolanın tam olarak 256 bit olacağı biçimde kısaltılır.

256 bit salt değeri oluşturun veya elde edin

Sonraki adım, daha sonraki bir adımda parolayla birleştirilecek bir 256 bit salt değeri elde etmektir. salt , parola oluşturmak için kullanıcı tarafından girilen bir değere eklenen veya kullanıcı tarafından girilen bir değerle birleştirilen rastgele bir değerdir. Salt değerini bir parolayla kullanmak, kullanıcı parola olarak gerçek bir sözcük veya yaygın bir terim seçtiğinde bile sistemin kullandığı parola+salt bileşiminin rastgele bir değer olmasını sağlar. Bu değerin rastgele oluşu, saldırganın parolayı tahmin etmek için bir sözcük listesi kullandığı sözlük saldırısına karşı korunmaya yardımcı olur. Ayrıca, salt değerini oluşturma ve şifreli yerel depoda saklama, bu değeri veritabanı dosyasının bulunduğu bilgisayardaki kullanıcı hesabına bağlar.

Uygulama getEncryptionKey() yöntemini ilk kez çağırıyorsa, kod bir 256 bit salt değeri oluşturur. Aksi halde, kod salt değerini şifreli yerel depodan yükler.

Salt, salt adlı bir değişkende saklanır. Kod, salt değerini şifreli yerel depodan yüklemeyi deneyerek onu daha önceden oluşturulmuş olup olmadığını belirler:

var salt:ByteArray = EncryptedLocalStore.getItem(saltKey); 
if (salt == null) 
{ 
    salt = makeSalt(); 
    EncryptedLocalStore.setItem(saltKey, salt); 
}

Kod yeni bir salt değeri oluşturduğunda, makeSalt() yöntemi 256 bit rastgele bir değer oluşturur. Değer şifreli yerel depoda saklandığından, bir ByteArray nesnesi olarak oluşturulur. makeSalt() yöntemi, rastgele bir değer oluşturmak için Math.random() yöntemini kullanır. Math.random() yöntemi bir defada 256 bit oluşturamaz. Bunun yerine, kod Math.random() yöntemini sekiz defa çağırmak için bir döngü kullanır. Her defasında 0 ve 4294967295 arasında (maksimum uint değeri) yer alan rastgele bir uint değeri oluşturulur. Uint değeri tam olarak 32 bit kullandığından, kolaylık sağlamak için kullanılır. ByteArray öğesine sekiz uint değeri yazılarak bir 256 bit değer oluşturulur. Aşağıdaki, makeSalt() yöntemine ilişkin koddur:

private function makeSalt():ByteArray 
{ 
    var result:ByteArray = new ByteArray; 
     
    for (var i:uint = 0; i < 8; i++) 
    { 
        result.writeUnsignedInt(Math.round(Math.random() * uint.MAX_VALUE)); 
    } 
     
    return result; 
}

Kod salt değerini Şifreli Yerel Depo'ya (ELS) kaydettiğinde veya bu değeri ELS'den aldığında, salt değerinin altında saklanacağı String anahtarına ihtiyaç duyar. Anahtarı bilmeden, salt değeri elde edilemez. Bu durumda, şifreleme anahtarı veritabanını yeniden açmak için her defasında yeniden oluşturulamaz. EncryptionKeyGenerator, varsayılan olarak SALT_ELS_KEY sabitinde tanımlanan ön tanımlı bir ELS anahtarı kullanır. Varsayılan anahtarı kullanmak yerine, uygulama kodu getEncryptionKey() yöntemine yapılan çağrıda kullanmak üzere bir ELS anahtarı da belirleyebilir. Varsayılan veya uygulama tarafından belirlenen salt ELS anahtarı, saltKey adlı bir değişkende saklanır. Bu değişken, daha önce gösterildiği gibi, EncryptedLocalStore.setItem() ve EncryptedLocalStore.getItem() öğelerine yapan çağrılarda kullanılır.

XOR operatörünü kullanarak 256 bit parolayı ve salt değerini birleştirin.

Kod, artık bir 256 bit parola ve bir 256 bit salt değerine sahiptir. Daha sonra, salt değeri ve bitiştirilmiş parolayı tek bir değer halinde birleştirmek için bit tabanlı XOR işlemini kullanır. Bu teknik, tüm olası karakterler aralığında yer alan karakterlerden oluşan bir 256 bit parola oluşturur. Gerçek parola girişi genellikle temel olarak alfanümerik karakterlerden oluştuğu halde bu ilke geçerlidir. Rastgeleliğin artırılması, kullanıcının uzun, karmaşık bir parola girmesini gerektirmeden olası parolalar kümesini genişletir.

XOR işleminin sonucu unhashedKey değişkeninde saklanır. İki değer üzerinde bit tabanlı bir XOR gerçekleştirme işlemi xorBytes() yönteminde olur:

var unhashedKey:ByteArray = xorBytes(concatenatedPassword, salt);

Bit tabanlı XOR operatörü ( ^ ) iki uint değerini alır ve bir uint değeri döndürür. (Bir uint değeri 32 bit içerir.) xorBytes() yöntemine iletilen giriş değerleri, String (parola) ve ByteArray (salt) değerleridir. Sonuç olarak, kod XOR operatörünü kullanarak her girişten bir defada birleştirilecek 32 bit ayıklamak için bir döngü kullanır.

private function xorBytes(passwordString:String, salt:ByteArray):ByteArray 
{ 
    var result:ByteArray = new ByteArray(); 
     
    for (var i:uint = 0; i < 32; i += 4) 
    { 
        // ... 
    } 
     
    return result; 
}

Döngü içinde ilk 32 bit (4 bayt) passwordString parametresinden ayıklanır. Bu bitler ayıklanır ve iki bölümlü bir işlemde bir uint ( o1 ) değerine dönüştürülür. İlk olarak, charCodeAt() yöntemi her karakterin sayısal değerini getirir. Daha sonra, sol shift operatörü kullanılarak bu değer uint değerindeki uygun konuma kaydırılır ( << ) ve kaydırılan değer o1 değerine eklenir. Örneğin, bitleri 24 bit sola kaydırmak için bit tabanlı sol shift operatörü ( << ) kullanılması ve bu değerin o1 değerine atanması yoluyla, ilk karakter ( i ) ilk 8 bit olur. İkinci karakter (i + 1 ), değerinin 16 bit sola kaydırılması ve sonucun o1 değerine eklenmesiyle, ikinci 8 bit olur. Üçüncü ve dördüncü karakterler de aynı şekilde eklenir.

        // ... 
         
        // Extract 4 bytes from the password string and convert to a uint 
        var o1:uint = passwordString.charCodeAt(i) << 24; 
        o1 += passwordString.charCodeAt(i + 1) << 16; 
        o1 += passwordString.charCodeAt(i + 2) << 8; 
        o1 += passwordString.charCodeAt(i + 3); 
         
        // ...

o1 değişkeni artık passwordString parametresinden 32 bit içerir. Daha sonra, readUnsignedInt() yöntemi çağrılarak salt değerinden 32 bit ayıklanır. 32 bit, o2 uint değişkeninde saklanır.

        // ... 
         
        salt.position = i; 
        var o2:uint = salt.readUnsignedInt(); 
         
        // ...

Son olarak, iki 32 bit (uint) değer XOR operatörü kullanılarak birleştirilir ve sonuç result adlı ByteArray öğesine yazılır.

        // ... 
         
        var xor:uint = o1 ^ o2; 
        result.writeUnsignedInt(xor); 
        // ...

Döngü tamamlandığında, XOR sonucunu içeren ByteArray döndürülür.

        // ... 
    } 
     
    return result; 
}

Anahtar için karma oluşturun

Bitiştirilen parola ve salt değeri birleştirildiğinde, sonraki adım SHA-256 karma algoritma aracılığıyla karma oluşturmak ve bu değeri daha güvenli kılmaktır. Değer için karma oluşturmak, saldırganın tersine mühendislik uygulamasını zorlaştırır.

Bu noktada kod, salt değeriyle birleştirilen bitiştirilmiş parolayı içeren unhashedKey adlı bir ByteArray öğesi içerir. ActionScript 3.0 core library (as3corelib) projesi, com.adobe.crypto paketinde bir SHA256 sınıfı içerir. ByteArray üzerinde SHA-256 karma gerçekleştiren ve onaltılı bir sayı olarak 256 bit karma sonucu içeren bir String döndüren SHA256.hashBytes() yöntemi. EncryptionKeyGenerator sınıfı, anahtar için karma oluşturmak üzere SHA256 sınıfını kullanır.

var hashedKey:String = SHA256.hashBytes(unhashedKey);

Karmadan şifreleme anahtarını ayıklayın.

Şifreleme anahtarı, tam olarak 16 bayt (128 bit) uzunluğunda olan bir ByteArray olmalıdır. SHA-256 karma algoritma sonucu her zaman 256 karakter uzunluğundadır. Sonuç olarak, son adım geçerli şifreleme anahtarı olarak kullanılmak üzere karma oluşturulan sonuçtan 128 bit seçmektir.

Kod, EncryptionKeyGenerator sınıfında generateEncryptionKey() yöntemini çağırarak anahtarı 128 bite indirger. Daha sonra bu yöntemin sonucunu getEncryptionKey() yönteminin sonucu olarak döndürür:

var encryptionKey:ByteArray = generateEncryptionKey(hashedKey); 
return encryptionKey;

İlk 128 biti şifreleme anahtarı olarak kullanmak gerekmez. İstediğiniz bir noktadan başlayan bir bit aralığı seçebilir, diğer bitleri seçebilir veya başka bir bit seçme yolu kullanabilirsiniz. Önemli olan, kodun 128 ayrı bit seçmesi ve her defasında aynı 128 bitin kullanılmasıdır.

Bu durumda, generateEncryptionKey() yöntemi şifreleme anahtarının 18. baytında başlayan bit aralığını kullanır. Önceden belirtildiği gibi, SHA256 sınıfı onaltılı bir sayı olan 256 bit karma içeren bir String değeri döndürür. 128 bitlik tek bir blok, bir defada ByteArray öğesine eklemek için çok fazla bayt içerir. Sonuç olarak, kod karakterleri onaltılı String öğesinden ayıklamak, bunları gerçek sayısal değerlere dönüştürmek ve ByteArray öğesine eklemek için for döngüsünü kullanır. SHA 256 sonuç String'i 64 karakter uzunluğundadır. 128 bit aralığı String'de 32 karaktere eşittir ve her karakter 4 biti temsil eder. ByteArray öğesine ekleyebileceğiniz en küçük veri artışı, hash String'de iki karaktere eşit olan bit bayttır (8 bit). Sonuç olarak, 2 karakter artışında döngü 0'dan 31'e kadar (32 karakter) sayar.

Döngü içinde, kod önce geçerli karakter çifti için başlangıç konumu belirler. İstenen aralık dizin konumu 17'deki (18. bayt) karakterde başladığından, position değişkenine geçerli yineleyici değeri ( i ) + 17 atanır. Kod, geçerli konumda iki karakter ayıklamak için String nesnesinin substr() yöntemini kullanır. Bu karakterler hex değişkeninde saklanır. Daha sonra, kod hex String'ini onlu tamsayı değerine dönüştürmek için parseInt() yöntemini kullanır. Bu değeri byte değişkeninde saklar. Son olarak, kod writeByte() yöntemini kullanarak byte içindeki değeri result ByteArray öğesine ekler. Döngü tamamlandığında, result ByteArray 16 bayt içerir ve veritabanı şifreleme anahtarı olarak kullanılmaya hazırdır.

private function generateEncryptionKey(hash:String):ByteArray 
{ 
    var result:ByteArray = new ByteArray(); 
     
    for (var i:uint = 0; i < 32; i += 2) 
    { 
        var position:uint = i + 17; 
        var hex:String = hash.substr(position, 2); 
        var byte:int = parseInt(hex, 16); 
        result.writeByte(byte); 
    } 
     
    return result; 
}