5 Haziran 2017 Pazartesi

Kripto

Giriş
Hash, CRC ve Kripto ile ilgili aldığım notlar aşağıda.

Hash'lenen Değerin Bit Uzunluğu/Hash Bit Uzunluğu
Basit bir kural şu. Eğer hash'lenen değerin bit uzunluğu hash'in bit uzunluğundan büyük ise mutlaka çarpışma (collision) olacaktır. Zaten hiç bir hash mükemmel olmadığı çarpışma olması kaçınılmazdır.

Tek Yönlü Hash
Hash'ler tek yönlüdür ve güvenlik için 70'lerden beri kullanılırlar. 90'larda salt + hash şeklinde kullanımı başlamıştır. Iterative hash'ler ise 2010'lardan itibaren kullanılıyorlar.

Standart Hash Fonksiyonları
Gömülü Proje - Hash yazısına taşıdım.

Basit Hash Fonksiyonları
Additive Hash
Çok basit olduğu ve iyi bir dağılım sağlamadığı söyleniyor. İyi bir dağılım sağlamamasının sebebi "abc" ve "cba" ve "cab" için aynı değeri dönmesi. Yani "commutative operation", türkçesi "değişme özelliği" 'ni dikkate almaması.

Örnek: ub4 unsigned integer olarak düşünülebilir.



Sum of Squares
Bu hash yöntemi pek yaygın değil ancak kullanıldığını gördüğüm için not etmek istedim. 
Multiplicative hash is sum of the squares of all bytes. Örnek:
unsigned  hash_func (char* string, unsigned len) {
  unsigned sum = 0;
  unsigned value = 0;
  for (; len > 0; len --) {
    value = (unsigned) (*string++ & 0xFF)
    sum += value * value;
  }
  return sum;
}


Rotating Hash
XOR hash'e göre biraz daha iyi. Örnek:

Knut's Multiplicative Method
Knut's Multiplicative Method yazısına taşıdım.


Programlama Dillerinde Bulunan Hash Gerçekleştirimleri
Java
Javadaki basit bir hash fonksiyonu için buraya bakabilirsiniz. Fonksiyonun yaptığı şey verilen değerin belli alanlarından bitleri almak ve bunları XOR'lamak .

Buradaki soruda XOR ile bitlerin daha iyi dağılım gösterdiği yazılı.XOR'lamanın tek problem XOR'un simetrik olması. Yani a.hashCode() ^ b.hashCode() ve b.hashCode() ^ a.hashCode() aynı değeri verir.
Ama bence bu büyük bir problem değil.

C++
STL ile std::hash<T> metodu geliyor.Bu metodun generic çalışmasına dikkat çekilmiş.
Örnek:
std::hash<std::string> str_hash;
std::string str1 = "Test";
size_t hash = str_hash (str1);
std::hash() farklı arka arkaya çağırılarak bir seed değerine combine işlemini gerçekleştiremiyor. boost kütüphanesi ile gelen hash_combine() metodu ile bu iş çok kolay. Eğer boost kullanmak istemiyorsak aşağıdaki generic kod kullanarak yapılabilir.
template <class T>
inline void hash_combine(std::size_t & seed, const T & v)
{
  std::hash<T> hasher;
  seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}

namespace std
{
  template<typename S, typename T> struct hash<pair<S, T>>
  {
    inline size_t operator()(const pair<S, T> & v) const
    {
      size_t seed = 0;
      ::hash_combine(seed, v.first);
      ::hash_combine(seed, v.second);
      return seed;
    }
  };
}


Boost
hash_combine ile mevcut değer bir başka değer ile birleştiriliyor. Kullanılan formüldeki sabit burada açıklanıyor.

hash_combine metodunu kullanmak için hash.hpp dosyasını dahil etmek gerekir.
#include <unordered_map>
#include <boost/functional/hash.hpp>

using namespace std;
using namespace boost;

unordered_map<pair<int, int>, int, hash<pair<int, int>>> table;

Bir başka örnek:
#include <boost/functional/hash.hpp>
size_t  seed = 0;
int val = //...
boost::hash_combine (seed,val);


Kriptografik Hash Fonksiyonları



MD5 - Kullanmayın
MD5 yazısına taşıdım

SHA-0
SHA-0 yazısına taşıdım.



SHA-1 Kullanmayın
SHA-1 yazına taşıdım.

SHA-2
SHA-2 yazısına taşıdım.

CRC Fonksiyonları
Checksum başlıklı yazıya taşıdım.

Pairing Fonksiyonları
Pairin Fonksiyonları Hash ve CRC gibi verilen veriden başka bir sayı üretir. Ancak diğerlerinden farklı olarak üretilen sayıdan daha sonra geriye dönerek veriyi elde etmek mümkün.

Belli Aralıktaki İki Sayıyı Birleştirmek
Aşağıda 0 - 100,000 arasındaki sayıları birleştiren ve tekrar ayıran bir örnek var.

Define f(n,m)=n+1000000m. Then n=f(n,m)mod1000000, and m=f(n,m)n1000000.

Bu örneği genel bir formül haline getirmek istersek:

Bit Kaydırma Yöntemi
İki byte olduğunu bildiğimiz iki sayıyı dört byte'a sığdırmak mümkün. Örnek:

KRİPTOLAR
Her kriptoda confidentiality (mesajın istenmeyen birisi tarafından okunamamasını ağlamak) ve authenticity (belirtilen kişiden geldiğini doğrulamak) önem taşır.

Confidentiality için gönderen alıcının public anahtarını kullanarak mesajı şifreler.

Authentication için mesajın imzalanması (signing) gerekir. İmza için mesajı gönderen kendi private anahtarını kullanır. Alıcı tarafa gönderenin public anahtarı ile mesajı doğrular.

Diffie-Hellman
Diffie-Hellman yazısına taşıdımö

DES
DES yazısına taşıdım.

AES
AES yazısına taşıdım.

RSA
RSA yazısına taşıdım.



Hiç yorum yok:

Yorum Gönder