Ne şifreleme algoritması çerezleri şifrelemek için en iyisidir?

11 Cevap php

Ben kurabiye şifrelemek için 'en iyi' şifreleme algoritması hakkında bilgi arıyorum.

Ben aşağıdaki şartları HAVA:

  • It must be fast
    encrypting and decrypting the data will be done for (nearly) every request

  • Bu küçük veri setleri, yaklaşık 100 karakter veya daha az tipik dizeleri çalışacaktır

  • Bu güvenli olmalı, ama biz bankacılık işlemleri güvence konum gibi değil

  • Biz SHA1 ve benzerleri dışında böylece bilgilerin şifresinin açılması için mümkün olması gerekmektedir.

Now I've read that Blowfish is fast and secure, and I've read that AES is fast and secure. With Blowfish having a smaller block size.

I think that both algorithms provide more than adequate security? so the speed would then become the decisive factor. But I really have no idea if those algorithm are suited for small character string and if there are maybe better suited algorithm for encrypting cookies.

So my question is:
What encryption algorithm is best for encrypting cookie data?

Update
To be more precise, we want to encrypt 2 cookie: one with session information and the other with 'remeber me' information.

Platformu VPS Linux apache modülü olarak PHP.

Update 2
I agree with cletus that storing any information in a cookie is insecure.

Ancak, biz 'Beni hatırlamak' özelliğini uygulamak için bir şartı var. Bu konuda gitmek için kabul edilen yol, bir cookie ayarlayarak gereğidir. Istemci bu tanımlama sunar Eğer o / o geçerli bir kullanıcı adı şifre kombinasyonunu sunulan sanki, o izin verilir (neredeyse) eşit haklara sahip sistemine erişmek.

So we at least want to encrypt all data in the cookie so that it:
a) malicious users can't read it's contents,
b) malicious users can't fabricate their own cookie or tamper with it.

(Çerezleri tüm veriler ayıklanmış ve kontrol geçerliliği için biz onunla bir şey yapmadan önce, ama bu başka bir hikaye edilir)

Oturum çerezi daha sessionId / timestamp hiçbir şey içermiyor. Muhtemelen şifreleme olmadan kullanılmış olabilir, ama ben şifreleyerek hiçbir zarar görüyor musun? (Zamanın hesaplama dışında).

So given that we have to store some data on in a cookie, what is the best way to encrypt it?

Update 3
The responses to this question made me reconsider the chosen approach. I can indeed do the same without the need for encryption. Instead of encrypting the data, I should only send out data that is meaningless without it's context and cannot be guessed.

However, I'm also at a loss:
I thought that encryption enabled us send data out in to the BigBadWorld™, and still be (fairly) sure that nobody could read or tamper with the it...
Wasn't that the whole point of encryption?

Ama doğru itme aşağıdaki reaksiyonlar: güvenliğini gerçekleştirmek için şifreleme güvenmiyorum.

What am I missing??

11 Cevap

No real reason not to go with AES with 256 bits. Make sure to use this in CBC mode, and PKCS#7 padding. As you said, fast and secure.

Ben Ancak Blowfish bu kötü durum için kılacak, uzun kurulum süresi büyük bir dezavantajı var ... Blowfish marjinal daha hızlı olabilir (test değil) okudum. Ayrıca, AES daha "kanıtlanmış" dir.

This assumes that it really is necessary to symmetrically encrypt your cookie data. As others have noted, it really shouldnt be necessary, and there are only a few edge cases where there's no other choice but to do so. Commonly, it would better suit you to change the design, and go back to either random session identifiers, or if necessary one-way hashes (using SHA-256).
In your case, besides the "regular" random session identifier, your issue is the "remember me" feature - this should also be implemented as either:

  • veritabanında saklanan ve bir kullanıcı hesabı ile eşleştirilir uzun bir rasgele sayı;
  • ya da bir anahtarlanmış hızlı arama (örneğin, HMAC) ihtiva eden, örneğin Kullanıcı adınızı, zaman damgası, mebbe tuz VE gizli bir sunucu anahtar. Bu tabii ki tüm sunucu tarafı kontrol edilebilir ...

Seems like we've gotten a little off topic of your original, specific question - and changed the basis of your question by changing the design....
So as long as we're doing that, I would also STRONGLY recommend AGAINST this feature of persistent "remember me", for several reasons, the biggest among them:

  • Birisi onlara kullanıcının kimliğini aldatmak için (ve daha sonra muhtemelen onun şifresini değiştirmek) sağlayan, anahtarını unutmayın kullanıcıyı çalmak olabilir çok daha olası hale getirir;
  • CSRF - Cross Site Request Forgery. Sizin özellik etkin bir anonim saldırganın habersiz kullanıcıların bile aslında oturum olmadan, uygulama için "doğrulanmış" istekleri göndermek için neden sağlayacak

Bu iki ayrı konular üzerinde dokunuyor.

İlk olarak, session hijacking. Bir üçüncü taraf, diyelim ki, başkasının detayları kimliği doğrulanmış bir çerez ve kazançlar erişim keşfeder yerdir.

İkinci olarak, bir session data security. Bu Benim size (örneğin kullanıcı adı olarak) çerez verileri saklamak anlamına gelir. Bu iyi bir fikir değil. Bir müşteri ne istediklerini göndermek için ücretsiz olması nedeniyle herhangi bir tür veri (bakılmaksızın JavaScript doğrulama ve / veya HTML uzunluğu kısıtlamaları kullanmak ne varsa) HTML form verilerini güvenilmez gibi temelde güvenilmez.

Sık sık (haklı olarak) HTML form verilerini sterilize ama çerez bilgileri körü körüne yüz değeri kabul edilecek savunan insanlar bulabilirsiniz. Büyük hata. Aslında, ben çerez herhangi bir bilgi depolamak asla. Ben bir oturum anahtarı olarak görmek ve hepsi bu.

If you intend to store data in a cookie I strongly advise you to reconsider.

Simetrik şifreleme brute-force saldırısına duyarlı olduğundan bu veri şifreleme bilgileri herhangi bir daha trustworth yapmaz. Açıkçası AES-256 DES (heh) ama güvenlik 256-bit mutlaka öyle sandığınız kadar anlamına gelmez, diyelim ki, daha iyidir.

Bir kere, tuzları, tipik bir algoritmaya göre üretilen veya saldırıya aksi duyarlı vardır.

Başka için, çerez veri crib saldırıları için bir başbakan adayı. Olduğu bilinen veya kullanıcı adı şifreli veri olduğunu şüpheleniliyorsa hey, beşik var olacaktır.

Bu ilk nokta bizi geri getiriyor: kaçırma.

Bu işaret gerektiğini paylaşılan barındırma (bir örnek olarak) PHP ortamlarında sizin oturum verileri sadece dosya sisteminde saklanır ve mutlaka bunun için hangi site bilmiyorum ancak aynı ana başkaları tarafından okunabilir. Yani düz metin şifreleri, kredi kartı numaraları, kapsamlı kişisel bilgilerinizi veya aksi takdirde sadece oturumda bir anahtar saklanması ve gerçek hassas saklamak, daha henüz bazı şifreleme şeklinde ya da olmadan bu tür ortamlarda oturum verileri gibi hassas kabul edilebilir bir şey saklamak asla Bir veritabanında veri.

Note: Yukarıdaki PHP özgü değildir.

Ama bu sunucu tarafı şifreleme bulunuyor.

Şimdi bazı ekstra veri ile bir oturum şifreleyerek kaçırma daha güvenli hale getirecek iddia olabilir. Yaygın bir örnek, kullanıcının IP adresidir. Sorun birçok kişi çok farklı yerlerde (örneğin Wifi noktaları, iş, ev) de aynı PC / dizüstü bilgisayar kullanmaktır. Ayrıca pek çok ortamlarda özellikle kurumsal ortamlarda, kaynak adresi olarak IP adreslerinin çeşitli kullanır.

Ayrıca kullanıcı ajan kullanabilir ama bu guessable bulunuyor.

Yani gerçekten, bildiğim kadarıyla söyleyebilirim, tüm çerez şifreleme kullanmak için gerçek bir neden yoktur. Ben orada olduğunu düşünüyorum yapmadım ama bu sorunun ışığında doğru ya da yanlış ya kanıtlanmış olması aramaya gitti. Ben insanların, çerez verileri şifrelemek için yollar önermek şeffaf Apache modülleri ile bunu, ve böylece, ancak hakkında birkaç konuları buldu bütün bu (imho yapmanız gereken) bir çerez saklanan verilerin korunması motive gibiydi.

Ben bir oturum anahtarı başka bir şey temsil eden bir çerez şifrelemek için bir güvenlik argüman görmek için henüz ettik.

Birisi aksine bir şeyler işaret eğer ben mutlu yanlış kanıtlanmış olacaktır.

PHP bu yöntemi kullanmak isteyen aracılığıyla okuyanlar için. İşte 256bit AES kullanarak bir çalışma örneği.

function encrypt($text, $salt) 
{ 
    return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $salt, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND)))); 
} 

function decrypt($text, $salt) 
{ 
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $salt, base64_decode($text), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))); 
}

Sonra çerez kaydetmeye

setcookie("PHPSESSION", encrypt('thecookiedata', 'longsecretsalt'));

ve sonraki sayfada okumak için:

$data = decrypt($_COOKIE['PHPSESSION'], 'longsecretsalt');

Hem de çok güçlü olanlar da, AES bir standarttır.

Küçük veri parçalarını güvenlik gelince: küçük - iyi. Daha az şifreli veri maruz, uzun süre tuşunu kullanabilirsiniz. Risklere maruz kalmadan sisteminizi verilen algoritma bir anahtar içinde şifreli olabilir ne kadar veri teorik bir sınır her zaman vardır.

Sen güvenli EAX modunda AES kullanarak istediğiniz şeyi elde edebilirsiniz. Şifreli şifresiz daha büyük olacaktır; Bu güvenli şifreleme için normaldir.

Saldırgan elbette şifreli sizin düz metin uzunluğunu bilecek, ama onlar başka bir şey belirlemek mümkün olmamalıdır.

Rastgele AES anahtarları üretmek.

Emin olun ve her şifreleme için taze bir seferlik kullanın ve tek bir amaç için şifreli bir şey (başka varlık olarak sunulan olmadığından emin olmak için "ilişkili veri" alanını kullanın böylece kullanıcı adı ve çerez adı gibi şeyler gidebiliriz orada)

the reactions below push toward: Do not trust encryption to accomplish security.

Daha "Bir şifreleme uzmanı değiliz eğer yanlış almak ne kadar kolay hafife edeceğiz". Örneğin, bu parçacığı başka hiç kimse AFAICT iki ortak acemi hataları kapsamaktadır zincirleme modları veya mesaj bütünlüğü, tartışmıştır.

Neden çerezi şifrelemek istiyorsun?

Gördüğüm kadarıyla, iki olgu vardır: Eğer istemci anahtarını vermek, ya da yoktur ya.

Eğer müşteriye anahtarını vermek istemiyorsanız, o zaman neden onlara verileri veriyorsun? Eğer zayıf şifreleme (açıkça değilsin ki) kırma ile bazı garip oyun oynuyorsanız sürece, siz de sunucu üzerinde veri depolamak olabilir.

Eğer do müşteriye anahtarını teslim ederseniz, o zaman neden ilk etapta bunu şifrelemek mi? Eğer anahtar iletişimi şifrelemek yoksa, o zaman çerez şifreleyerek tartışmalı: a MITM çerez bakmak ve size istediği herhangi bir çerez gönderebilir. Eğer istemci bir şifreli kanal, depolanmış verileri şifreleyerek, neden fazladan yükü kullanırsanız?

Eğer çerez okuma istemci makine üzerinde diğer kullanıcılar hakkında endişeli iseniz, vazgeçmek ve tarayıcı iyi izin bitlerini ayarlar varsayıyorum :)

Eğer çerez şifrelemek eğer çalıntı (ve un-düzenlenmiş) eğer hala doğru hesabınıza korsan yol açacaktır, çünkü sunucu hala, bu nedenle herhangi bir şifreli çerez anlamsız olduğunu (aynı anahtarla kontrol etmek için) okumak için çözmek zorunda . Onun hiç şifreli kadar güvensiz.

Ben çerez çalınmasında asıl mesele sunucu ve istemci arasında bağlantı olduğuna inanıyorum. Ev sahibi tarafından sağlanan SSL bağlantısını kullanın.

Çerezinizle gelince, siz (her oturum değiştirmek var), veritabanındaki kullanıcı başına uzun bir rasgele id yapmak gerekir ve sadece ayarladığınız çerez veya oturum gibi. Anahtarını içeren çerez php ile kontrol ve veritabanındaki bir hesaba ya da tabloya eşit ise, normal gibi web sayfasında veri dökümü olabilir.

Önceki yorumlarda birkaç kez işaret ettiği gibi, sen must Eğer kullanıcıya göndermek ve geri kabul herhangi bir şifreli için integrity protection geçerlidir. Aksi korumalı veri değiştirilebilir, ya da şifreleme anahtarı kurtarıldı.

Özellikle PHP dünya (bkz. PHP cryptography - proceed with care) bu görmezden kötü örneklerle dolu ama bu herhangi bir dil için geçerlidir.

Gördüğüm Birkaç iyi örneklerinden biri işi yapmak için kombine şifreleme kimlik doğrulama modunu kullanır PHP-CryptLib hangi. Python için pyOCB benzer işlevsellik sunuyor.

(Aynı zamanda Rijndael olarak da bilinir) AES en popüler olanıdır. Blok boyutu sadece 16-bayt, ve sen "etrafında 100 karakter" bahsediyoruz, 128-bit.

I think that "giving away" any data even encrypted when it is about username and password is not good ... There are many JS that can sniff it ... I suggest you create in users DB table a field cookie_auth or whatever ...

ilk girişten sonra toplamak: akım: tarayıcı, IP, bazı kendi tuz anahtarı, artı hostname VAR ans ...

create a hash and store in that field ... set a cookie ... when cookie "responds" compare all of these with the stored hash and done ...

Birisi bir çerez "çalmak" bile onlar :-) kullanmak mümkün olmayacaktır

Bu :-) yardımcı olur umarım

feha vision.to

Buna ek olarak, mcrypt_encrypt denedim ve bir şey lütfen unutmayın. Bunu yaparsanız base64_encode(mcrypt_encrypt(...)).

ve sonra sen base64_decode ve çıkış şifreli veri yapmak (echo). Muhtemelen vidalı ve hiçbir şey göremiyorum edilecektir. Ancak, bunu yaparsanız mcrypt_decrypt( ... base64_decode($value) ). Sen orijinal verileri görürsünüz.