Web Crypto API ile web üzerinde şifreleme



  1. Web Crypto API ile web üzerinde şifreleme

Web geliştirmedeki en önemli konulardan biri güvenliktir. Web Crypto API ile, modern tarayıcılar artık geliştiricilerin istemci tarafındaki bilgileri de imzalayıp şifreleyebilecekleri bir araç sunuyor.


Güvenlik, web’de en önemli önceliktir. Örneğin, tarayıcının yalnızca uygulama güvenli bir bağlantı aracılığıyla teslim edilirse hizmet çalışanları veya Ödeme İsteği API’si gibi belirli özellikleri etkinleştirdiği W3C Güvenli Bağlamlar özelliğinin olması boşuna değildir. Ancak kullanıcı koruması daha da ileri gider. Bir tarayıcı, uygulamanın çalıştığı sistemin birçok arayüzüne erişim sağlar. Tipik olarak, mikrofon veya kamera, aynı zamanda sistemden gelen push bildirimleri de buna girer. Geliştiriciler, bu arabirimlere JavaScript aracılığıyla erişebilir, ancak yalnızca kullanıcılar bu erişime izin verdikten sonra. Bu nedenle, örneğin arka planda mikrofonu etkinleştirmek ve böylece hemen hemen her terminali bir casus cihaza dönüştürmek mümkün değildir.

Ancak, bir sorun uzun süre bozulmadan kaldı – tarayıcıdaki bilgilerin şifrelenmesi. Karma bilgi gibi basit standart görevler için bile işlevlerin dahili olarak yazılması veya harici bir kitaplığın kullanılması gerekiyordu. Bu, uygulamada istemciye gönderilmesi gereken ek kaynak kodu dezavantajına sahip olmakla kalmaz, aynı zamanda bu tür algoritmaların JavaScript’te yürütülme hızı, tarayıcıda yerel olarak uygulanmış gibi performans göstermez. Bu sorun, Web Kripto API’sı tarafından çözülür. Bu arabirim, örneğin istemci tarafı imzaların ve şifrelemenin uygulanabileceği bir dizi işlev sunar.

destek


Caniuse.com’a bir bakış, Chrome, Firefox, Edge ve Safari’nin Web Crypto API’yi tam olarak desteklediğini ortaya koyuyor. Yalnızca Internet Explorer ve Opera Mini burada hala sorunlara neden oluyor. Internet Explorer 11, Web Crypto API’yi zaten desteklemektedir, ancak belirtimin eski bir sürümündedir.

Web Crypto API, tarayıcının ayrılmaz bir parçası olduğundan, geliştiriciler arayüzün işlevlerini doğrudan, yani içe aktarma yönergeleri olmadan kullanabilirler. Aşağıdaki kod örneği, uygulamanın daha sonra gerçek şifreleme veya imzalama için başka bir anahtar oluşturmak için kullanabileceği bir parolaya dayalı olarak tarayıcıda bir PBKDF2 anahtarının nasıl oluşturulabileceğini gösterir:

(async () => {
const enc = new TextEncoder();
const pw = 'T0p5ecret!';
const key = await crypto.subtle.importKey(
'raw',
enc.encode(pw),
'PBKDF2',
false,
['deriveKey']
);
// ... work with the key
})();



Web Crypto API’sine window.crypto (veya kısaca kripto) nesnesi aracılığıyla erişilir. Bu arabirimin işlevlerinin çoğu asenkrondur ve sözlerle çalışır ve örnekteki gibi async/await ile kullanılabilir.

Artık iyi olan tarayıcı desteğine ek olarak, Web Crypto API de Node.js’de yolunu bulmuştur. Sürüm 15’ten bu yana, şu anda hala deneysel olan modül, Node.js çekirdeğinin bir parçasıdır (ancak bu yeni “webcrypto” modeli, halihazırda var olan “crypto” modülüyle karıştırılmamalıdır). Tarayıcıdan farklı olarak, geliştiricilerin önce aşağıdaki kod örneğinde olduğu gibi işlevselliği buraya entegre etmesi gerekir:

import {webcrypto} from 'crypto';
const enc = new TextEncoder();
const pw = 'T0p5ecret!';
const key = await webcrypto.subtle.importKey(
'raw',
enc.encode(pw),
'PBKDF2',
false,
['deriveKey']
);

console.log(key);


Web Crypto API için erken bir amaç, rastgele sayılar üretme gibi nispeten önemsiz bir problemden gelir.

rastgele numaralar


JavaScript standardı, rasgele sayılar üretme yöntemini sağlar Math.random() Önceki. Bir JavaScript uygulamasında kullanılabilecek, 0 ile 1 arasında rastgele bir kayan noktalı sayı döndürür. Standart, bu yöntemin tam olarak uygulanmasını tarayıcı üreticilerine bırakır ve uygulamalar platformdan platforma değişir. Ancak hepsinin ortak noktası, kriptografik olarak güvenli bir değişken olmamasıdır. Bu, geliştiricilerin güvenlik açısından kritik algoritmalar için bu yöntemi kullanmaması gerektiği anlamına gelir. Neyse ki, Web Crypto API şunları sağlar: getRandomValues()Bu sorunu çözen ve güvenli rasgele sayılar üreten bir yöntem. Aşağıdaki kod bloğu, bu yöntemin pratikte nasıl kullanıldığını göstermektedir:

const randomNumbers = new Uint32Array(1);
crypto.getRandomValues(randomNumbers);
console.log(randomNumbers[0]);

the getRandomValues()Yöntem, yazılan tamsayılardan oluşan bir dizi alır; yani, Uint8Array, Uint16Array veya Uint32Array. Dizinin boyutuna bağlı olarak, farklı sayıda rasgele sayı üretilir. Örneğimizde 32 bitlik rastgele bir sayı üretiliyor. Bu, kriptografik olarak güvenlidir ve güvenlikle ilgili sorunları gidermek için de kullanılabilir.

Web Crypto API’nin gerçekten harika özellikleri, SubtleCrypto arayüzünün arkasında veya özellikle kriptografik nesnenin ince özelliğinin arkasında gizlidir. Aşağıdaki bölümlerde, Web Crypto API için iki tipik uygulama alanına bakalım: imzalama ve şifreleme.

imza


Web uygulamalarında, geliştiriciler tipik olarak, gönderen ve alıcı arasında değiş tokuş edilen bilgilere yetkisiz bir üçüncü tarafın müdahale etmemesini sağlamak için dijital imzalar kullanır. Web Crypto API, bilgileri imzalamak için bir dizi algoritmayı destekler. Bunun örnekleri, aşağıdaki örnekte kullanılan RSA-PSS, AES-GCM veya HMAC’dir. İmzalarken, Web Crypto API, uygulamanın kendisi tarafından oluşturulan anahtarları veya içe aktarılan bir yabancı anahtarı kullanır. Varyanta bağlı olarak, geliştiriciler generateKey()– ya da importKey()-Yöntem. Aşağıdaki örneğin sorunsuz çalışması için kod, HMAC anahtarını kendisi oluşturur ve bunu imzalamak ve ardından imzayı doğrulamak için kullanır:

(async () =>{
const message = (new TextEncoder()).encode('Hallo Welt');
// generate the key
const key = await crypto.subtle.generateKey({
name: 'HMAC',
hash: {name: 'SHA-256'}
}, false, ['sign', 'verify']);

// sign the message
const signature = await crypto.subtle.sign(
{name: 'HMAC'},
key,
message
);

// print the signature
console.log(new Uint8Array(signature));

// verify the signature
const isValid = await crypto.subtle.verify(
{name: 'HMAC'},
key,
signature,
message
);
console.log('isValid?', isValid);
})();


Kod, Web Kripto API’sinin iki temel özelliğini çok iyi gösterir:

  • Sözler: Hemen hemen tüm arabirim yöntemleri eşzamansızdır ve bu eşzamansızlığı işlemek için vaatler kullanır. Bu paradigmanın bir avantajı, geliştiricilerin kaynak kodda async/await ile çalışabilmeleri ve böylece kaynak kodun okunmasını zorlaştıran ek geri arama işlevleri uygulamak zorunda kalmamasıdır.
  • Yazılan Diziler ve ArrayBuffer’lar: Web Crypto API, bilgi alışverişi yapmak için genellikle yazılan diziler ve ArrayBuffer nesneleri ile dahili olarak çalışır. Örneğin, kabul et sign()– Ve verify()-Yöntemler A Uint8Array-TextEncoder kullanılarak oluşturulan nesne. Dönüşü sign()Yöntem, yazılan bir diziye dönüştürülen ve konsolda görüntülenebilen bir ArrayBuffer’dır. Bu veri yapılarının kullanılmasının nedeni, örneğin karakter dizilerinden daha bilgi işlemek ve değiş tokuş etmek için daha uygun olmalarıdır.
Örnekteki kaynak kodu, öncelikle karakter dizisinin şu şekilde şifrelenmesini sağlar: Uint8Arraydosya için giriş biçimi sign()– Ve verify()yöntem mevcuttur. Ardından yeni bir anahtar oluşturun. the generateKey()Yöntem, geliştiricinin çağrıldığında anahtarın amaçlarını belirtmesini bekler, bu durumda bunlar “işaretle” ve “doğrula”dır. Bir uygulama, burada belirtilmeyen bir işlem için bir anahtar kullanıyorsa, JavaScript, bu tür işlemler için anahtara izin verilmediğini belirten bir DOM istisnası atar. Anahtar ve kodlanmış karakter dizisi ile, sign()Yöntem bir imza alır ve onu bir ArrayBuffer olarak döndürür.

muadili sign()yöntem verify()-Yöntem. Örneğin, kullanılan algoritmanın adını içeren bir yapılandırma nesnesini kabul edin. Ayrıca anahtar, imza ve karakter dizilerinin de kontrol edilmesi gerekmektedir. Sonucu sign()-call, imzanın geçerli olup olmadığını gösteren bir boole değeridir.

Bir uygulama, örneğin bir sunucuyla gizli bilgi alışverişi yapmak için imzalamayı kullanabilir. Her iki taraf da mesajların yol boyunca kurcalanıp kurcalanmadığını kontrol edebilir. Bunun ön koşulu, her iki tarafın da karşı tarafın anahtarını bilmesidir.

şifreleme


Web Crypto API kullanarak verileri şifrelemek, imza yerine şifrelenmiş bilgi olması dışında, verileri imzalamaya benzer şekilde çalışır. Aşağıdaki kod örneği, bir tuş bileşimi kullanır. İlk olarak, kaynak kodu, bir amaca sahip parola tabanlı bir anahtar oluşturur. deriveKey, daha sonra ikinci bir anahtarın türetildiği. Bu bir yandan şifreleme ve şifre çözme için parola kullanma imkanı sunarken, diğer yandan iki şifreleme mekanizmasının birleşimiyle güvenlik daha da artırılır. the encrypt()Yöntem daha sonra AES-GCM algoritmasını kullanarak bir metni şifrelemek için ikinci anahtarı kullanır. Şifre çözme daha sonra dosya ile yapılır. decrypt()yöntem ve ayrıca ikinci tuşla.

(async () => {
const enc = new TextEncoder();
const dec = new TextDecoder();
const pw = 'T0p5ecret!';
// create the first key
const key1 = await crypto.subtle.importKey(
'raw',
enc.encode(pw),
'PBKDF2',
false,
['deriveKey']
);

// create the second key
const key2 = await crypto.subtle.deriveKey(
{
name: "PBKDF2",
salt: crypto.getRandomValues(new Uint8Array(10)),
iterations: 250000,
hash: "SHA-256",
},
key1,
{ name: "AES-GCM", length: 256 },
false,
['encrypt', 'decrypt']
);
const iv = crypto.getRandomValues(new Uint8Array(10));
const encryptedMessage = await crypto.subtle.encrypt(
{
name: "AES-GCM",
iv,
},
key2,
new TextEncoder().encode('Hallo Welt')
);

console.log('encrypted data: ', new Uint8Array(encryptedMessage));

const decryptedBuffer = await window.crypto.subtle.decrypt(
{
name: "AES-GCM",
iv: iv,
},
key2,
encryptedMessage
);
const decryptedMessage = dec.decode(decryptedBuffer);

console.log('decrypted data: ', decryptedMessage);
})();


the encrypt()– Ve decrypt()-Yöntemler eskisi gibi çalışır sign() Ve verify()anahtarlar ve sonuçlarla çalışmak için yazılan diziler ve ArrayBuffer nesneleri ile.
İstemci tarafı şifrelemenin bir kullanımı, örneğin, istemcide saklanan bilgileri korumaktır. Çevrimdışı uygulamaların uygulanmasının artmasıyla birlikte, IndexedDB’deki diğer şeylerin yanı sıra tarayıcıda depolanan veri miktarı da artar. Bu depolama mekanizmalarının dezavantajı, tarayıcı geliştirici araçları kullanılarak kolayca okunabilmeleridir. Bu nedenle, yetkisiz üçüncü şahıslar tarayıcınıza erişim sağlarsa, tarayıcınızın tüm web belleğini okumaları mümkündür. Ancak veriler orada şifrelenirse, saldırganların bilgileri ele geçirmesi en azından biraz daha zor olacaktır. Bunun ön koşulu elbette şifre çözme için kullanılan anahtarın tarayıcıda da saklanmamasıdır.

Çözüm


Web Crypto API, JavaScript’te kriptografiyi işlemek için kullanılan ve artık tüm büyük tarayıcı satıcıları tarafından desteklenen düşük seviyeli bir API’dir. Node.js’de arabirim yalnızca istemcide değil, sunucu tarafında da mevcuttur, böylece kaynak kodu ve kitaplıklar iletişim yolunun her iki tarafında da yeniden kullanılabilir. Web Crypto API, kriptografik olarak güvenli değerler oluşturmaktan web uygulamalarında kullanılan bilgileri imzalamaya ve şifrelemeye kadar çeşitli kullanım durumlarını destekler. Bu arayüzün avantajı, ek kitaplıklar kurmaya gerek olmaması ve arayüzün yerel olarak tarayıcı tarafından uygulanmasından dolayı, aynı zamanda nispeten performanslı olmasıdır.
Web Crypto API, kullanıcılarının verilerini yetkisiz erişime karşı koruyan güvenli web uygulamalarına yönelik bir başka adımdır.


()



Haberin Sonu
 
Üst