SHA-2 Kriptografik Özet Fonksiyonu
1. SHA-256
SHA-2 Kriptografik Özet Fonksiyonu
1. SHA-256
SHA-256 kriptografik özet fonksiyonu 256 bitlik özet değer üretir. Şifrelenecek her blok 512 bit, 64 Byte uzunluğundadır ve blok yapısı Şekil 1.1.’te sunulmuştur. Özet alma işlemi öncelikle doldurma işlemiyle başlar. M mesajının bit cinsinden uzunluğu L olsun. Mesajın sonuna “1” bitini ve ardından, L +1+ k = 448 mod 512 denkleminin negatif olmayan en küçük çözümünü sağlayan k adet sıfır biti eklenir. Devamında ise ikilik düzende yazılmış L sayısına eşit 64 bitlik blok eklenir.

Şekil 1.1. SHA-256 blok yapısı
Örneğin, “abc” mesajı 8 · 3 = 24 bit uzunluğa sahiptir, 24’üncü bitin sonuna 1 eklenir ve ardından 448 — (24 + 1) = 423 tane sıfır bit ve en son mesajın uzunluk bilgisini içeren 64 bitlik veri eklenir. Böylece M mesajının uzunluğu 24 + 1 + 423 + 64 = 512 bit’e tamamlanmış olur.
Şekil 1.2.’de bir f işlev adımını içeren akış diyagramı görülmektedir. Diyagramda;
· İlk turda A-H = H01–8 olmak üzere, her biri 32 bit uzunluğunda sekiz elemanlı dizi yapısında değerleri önceden belirlenen başlangıç vektörüdür (Tablo 1.1). Sonraki turlarda, f işlevi çıktı değeri ile toplanarak bir sonraki işleve girdi olarak verilir.
· t, SHA-256 için 64 olarak belirlenmiş tur sayısıdır. Diyagramda belirtilen işlemler her f işlevi için tur sayısı kadar tekrarlanır.
· Wt, genişletilmiş mesaj bloğu olarak tanımlanır. İşleve girdi olarak verilen Mi bloğu SHA-256 için 32 bit uzunluğa sahip 16 eşit parçaya bölünür ve 1≤ j≤16 olmak üzere ilk 16 tur için giriş Wj = Mi(j) olarak kabul edilir.
· Kt ise her turda hesaplamaya dâhil edilen ve tur sayısına eşit olarak 64 elemanlı 32 bit uzunluğunda değere sahip bir dizidir (Tablo 1.2.).

Şekil 1.2. SHA-2 ailesi akış diyagramı

Tablo 1.1. Başlangıç vektörü

Tablo 1.2. K64 dizisi
f işlevi başlangıç vektörünün hesaplamaya dahil edilmesiyle başlar. 64 turluk döngünün her turunda Hi değerleri güncellenir ve bir kısmi özet fonksiyon değeri elde edilir.
Her tur sonunda yeni bir kısmi özet fonksiyonu değerini elde etmek için A’dan H’ye kadar olan değişkenlerin değerleri önceki kısmi özet fonksiyonuna eklenir. Son turdaki veri bloğu işlendikten sonra elde edilen değer, nihai özet fonksiyon değeridir. Tüm bu işlem basamaklarını açıklayan sözde kod aşağıda sunulmuştur.
h = h0 to h7 = IV
for each data block j do
A = h0; B = h1; C = h2; D = h3
E = h4; F = h5; G = h6; H = h7
for t= 0, t≤ 63, t=t+1 do
if t<16
Wt=Mt(i)
else
Wt = σ1(Wt-2) + Wt-7 + σ0(Wt-l5) + Wt-l6
T1 = H + ∑1(E) + Ch(E, F, G) + Kt + Wt
T2 = ∑0(A) + Maj(A, B, C)
H = G; G = F; F = E
E = D + T1
D = C; C = B; B = A
A = T1 + T2
end for
h0 = A + h0; h1 = B + h1
h2 = C + h2; h3 = D + h3
h4 = E + h4; h5 = C + h5
h6 = D + h6; h7 = E + h7
end for
Tablo 1.3. Algoritmada gerçekleştirilen Ch, Maj, ∑ ve δ mantıksal işlemlerinin ayrıntılarını göstermektedir. Burada ROTRn(x) n bitlik sağa döndürme işlemini ve SHRn(x) n bitlik sağa kaydırma işlemini temsil eder (Toz, Balasch, & Sheikh, 2016).

Tablo 1.3. Mantıksal işlemler
Kaynak Kodu
.NET Platformunda C# programlama dili ile yazılan SHA-256 kriptografik özet fonksiyonu kodu aşağıda sunulmuştur.
SHA-256 sınıfının GenerateFromFile metodu çağırılırken kullanılacak parametre değerleri:
fileName: Kriptografik Özet Fonksiyonu alınacak dosya adı (dosya yolu ile birlikte)
using System;
using System.IO;
namespace HashFunctions
{
internal class SHA256
{
private const int blockByteLength = 64, _paddingByteConst = 56;
uint h1;
uint h2;
uint h3;
uint h4;
uint h5;
uint h6;
uint h7;
uint h8;
public SHA256()
{
}
public string GenerateFromFile(String fileName)
{
FileStream fileStream = File.OpenRead(fileName);
string result = GenerateSHA256FromFile(fileStream).ToLower();
fileStream.Close();
return result;
}
private string GenerateSHA256FromFile(FileStream fS)
{
h1 = 0x6A09E667;
h2 = 0xBB67AE85;
h3 = 0x3C6EF372;
h4 = 0xA54FF53A;
h5 = 0x510E527F;
h6 = 0x9B05688C;
h7 = 0x1F83D9AB;
h8 = 0x5BE0CD19;
byte[] mBlockBytes = new byte[blockByteLength];
long mBlockCount = fS.Length / blockByteLength;
int lastBlockLength = (int)(fS.Length % blockByteLength);
byte[] mByteLength = BitConverter.GetBytes(fS.Length * 8);
BufferedStream bufferedStream = new BufferedStream(fS);
for (int i = 0; i <= mBlockCount - 1; i++)
{
bufferedStream.Read(mBlockBytes, 0, mBlockBytes.Length);
HashComputing(mBlockBytes);
}
if (lastBlockLength < _paddingByteConst)
{
mBlockBytes = new byte[blockByteLength];
bufferedStream.Read(mBlockBytes, 0, mBlockBytes.Length);
mBlockBytes[lastBlockLength] = 128;
for (int i = 0; i <= mByteLength.Length - 1; i++)
mBlockBytes[blockByteLength - (i + 1)] = mByteLength[i];
HashComputing(mBlockBytes);
}
else
{
mBlockBytes = new byte[blockByteLength];
bufferedStream.Read(mBlockBytes, 0, mBlockBytes.Length);
mBlockBytes[lastBlockLength] = 128;
HashComputing(mBlockBytes);
mBlockBytes = new byte[blockByteLength];
for (int i = 0; i <= mByteLength.Length - 1; i++)
mBlockBytes[blockByteLength - (i + 1)] = mByteLength[i];
HashComputing(mBlockBytes);
}
string hash = (h1.ToString("X").PadLeft(8, '0') +
h2.ToString("X").PadLeft(8, '0') +
h3.ToString("X").PadLeft(8, '0') +
h4.ToString("X").PadLeft(8, '0') +
h5.ToString("X").PadLeft(8, '0') +
h6.ToString("X").PadLeft(8, '0') +
h7.ToString("X").PadLeft(8, '0') +
h8.ToString("X").PadLeft(8, '0'));
return hash;
}
private void HashComputing(byte[] mBlock)
{
uint[] k = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
uint a = h1;
uint b = h2;
uint c = h3;
uint d = h4;
uint e = h5;
uint f = h6;
uint g = h7;
uint h = h8;
uint[] w = new uint[64];
for (int n = 0; n <= 63; n++)
{
if (n <= 15)
{
w[n] = (uint)mBlock[n * 4] * (uint)Math.Pow(16.0, 6.0) +
(uint)mBlock[n * 4 + 1] * (uint)Math.Pow(16.0, 4.0) +
(uint)mBlock[n * 4 + 2] * (uint)Math.Pow(16.0, 2.0) +
(uint)mBlock[n * 4 + 3];
}
else
{
uint s0 = (((w[n - 15]) >> (7)) | ((w[n - 15]) << (32 - (7)))) ^ (((w[n - 15]) >> (18)) | ((w[n - 15]) << (32 - (18)))) ^ (w[n - 15] >> 3);
uint s1 = (((w[n - 2]) >> (17)) | ((w[n - 2]) << (32 - (17)))) ^ (((w[n - 2]) >> (19)) | ((w[n - 2]) << (32 - (19)))) ^ (w[n - 2] >> 10);
w[n] = (s1 + w[n - 7] + s0 + w[n - 16]);
}
uint S1 = (((e) >> (6)) | ((e) << (32 - (6)))) ^ (((e) >> (11)) | ((e) << (32 - (11)))) ^ (((e) >> (25)) | ((e) << (32 - (25))));
uint ch = (e & f) ^ ((~e) & g);
uint t1 = h + S1 + ch + k[n] + w[n];
uint S0 = (((a) >> (2)) | ((a) << (32 - (2)))) ^ (((a) >> (13)) | ((a) << (32 - (13)))) ^ (((a) >> (22)) | ((a) << (32 - (22))));
uint maj = (a & b) ^ (a & c) ^ (b & c);
uint t2 = S0 + maj;
h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
h1 += a;
h2 += b;
h3 += c;
h4 += d;
h5 += e;
h6 += f;
h7 += g;
h8 += h;
}
}
}
2. SHA-512
SHA-512 kriptografik özet fonksiyonun, 512 bitlik özet değer üretir. Şifrelenecek her blok 1024 bit, 128 Byte uzunluğundadır ve blok yapısı Şekil 2.1.’de sunulmuştur. Hesaplama öncelikle doldurma işlemiyle başlar. M mesajının bit cinsinden uzunluğu L olsun. Mesajın sonuna “1” bitini ve ardından, L +1+ k = 896 mod 1024 denkleminin negatif olmayan en küçük çözümünü sağlayan k adet sıfır biti eklenir. Devamında ise ikilik düzende yazılmış L sayısına eşit 128 bitlik blok eklenir.

Şekil 2.1. SHA-512 blok yapısı
Örneğin, “abc” mesajı 8 · 3 = 24 bit uzunluğa sahiptir, 24’üncü bitin sonuna 1 eklenir ve ardından 896 — (24 + 1) = 871 tane sıfır bit ve en son mesajın uzunluk bilgisini içeren 128 bitlik veri eklenir. Böylece M mesajının uzunluğu 24 + 1 + 871 + 128 = 1024 bit’e tamamlanmış olur.
Bir f işlev adımını içeren akış diyagramında görüldüğü üzere(Bkz. Şekil 1.2);
· İlk turda A-H = H01–8 olmak üzere, her biri 64 bit uzunluğunda sekiz elemanlı dizi yapısında değerleri önceden belirlenen başlangıç vektörüdür (Tablo 2.1). Sonraki turlarda, f işlevi çıktı değeri ile toplanarak bir sonraki işleve girdi olarak verilir.
· t, SHA-512 için 80 olarak belirlenmiş tur sayısıdır. Diyagramda belirtilen işlemler her f işlevi için tur sayısı kadar tekrarlanır.
· Wt, genişletilmiş mesaj bloğu olarak tanımlanır. İşleve girdi olarak verilen Mi bloğu SHA-512 için 64 bit uzunluğa sahip 16 eşit parçaya bölünür ve 1≤ j≤16 olmak üzere ilk 16 tur için giriş Wj = Mi(j) olarak kabul edilir.
· Kt ise her turda hesaplamaya dâhil edilen ve tur sayısına eşit olarak 80 elemanlı 64 bit uzunluğunda değere sahip bir dizidir (Tablo 2.2).

Tablo 2.1. Başlangıç vektörleri

Tablo 2.2. K80 dizisi
f işlevi başlangıç vektörünün hesaplamaya dahil edilmesiyle başlar. 80 turluk döngünün her turunda Hi değerleri güncellenir ve bir kısmi özet fonksiyon değeri elde edilir.
Her tur sonunda yeni bir kısmi özet fonksiyonu değerini elde etmek için A’dan H’ye kadar olan değişkenlerin değerleri önceki kısmi özet fonksiyonuna eklenir. Son turdaki veri bloğu işlendikten sonra elde edilen değer, nihai özet fonksiyon değeridir. Tüm bu işlem basamaklarını açıklayan sözde kod aşağıda sunulmuştur.
h = h0 to h7 = IV
for each data block j do
A = h0; B = h1; C = h2; D = h3
E = h4; F = h5; G = h6; H = h7
for t= 0, t≤ 79, t=t+1 do
if t<16
Wt=Mt(i)
else
Wt = σ1(Wt-2) + Wt-7 + σ0(Wt-l5) + Wt-l6
T1 = H + ∑1(E) + Ch(E, F, G) + Kt + Wt
T2 = ∑0(A) + Maj(A, B, C)
H = G; G = F; F = E
E = D + T1
D = C; C = B; B = A
A = T1 + T2
end for
h0 = A + h0; h1 = B + h1
h2 = C + h2; h3 = D + h3
h4 = E + h4; h5 = C + h5
h6 = D + h6; h7 = E + h7
end for
Tablo 2.3. Algoritmada gerçekleştirilen Ch, Maj, ∑ ve δ mantıksal işlemlerinin ayrıntılarını göstermektedir. Burada ROTRn(x) n bitlik sağa döndürme işlemini ve SHRn(x) n bitlik sağa kaydırma işlemini temsil eder (Toz, Balasch, & Sheikh, 2016).

Tablo 2.3. Mantıksal işlemler
.NET Platformunda C# programlama dili ile yazılan SHA-512 kriptografik özet fonksiyonu kodu aşağıda sunulmuştur.
SHA-512 sınıfının GenerateFromFile metodu çağırılırken kullanılacak parametre değerleri:
fileName: Kriptografik Özet Fonksiyonu alınacak dosya adı (dosya yolu ile birlikte)
using System;
using System.IO;
namespace HashFunctions
{
internal class SHA512
{
private const int blockByteLength = 128, _paddingByteConst = 112;
ulong h1;
ulong h2;
ulong h3;
ulong h4;
ulong h5;
ulong h6;
ulong h7;
ulong h8;
public SHA512()
{
}
public string GenerateFromFile(String fileName)
{
FileStream fileStream = File.OpenRead(fileName);
string result = GenerateSHA512FromFile(fileStream).ToLower();
fileStream.Close();
return result;
}
private string GenerateSHA512FromFile(FileStream fs)
{
h1 = 0x6a09e667f3bcc908;
h2 = 0xbb67ae8584caa73b;
h3 = 0x3c6ef372fe94f82b;
h4 = 0xa54ff53a5f1d36f1;
h5 = 0x510e527fade682d1;
h6 = 0x9b05688c2b3e6c1f;
h7 = 0x1f83d9abfb41bd6b;
h8 = 0x5be0cd19137e2179;
byte[] mBlockBytes = new byte[blockByteLength];
long mlockCount = fs.Length / blockByteLength;
int lastBlockLength = (int)(fs.Length % blockByteLength);
byte[] mByteLength = BitConverter.GetBytes(fs.Length * 8);
BufferedStream bufferedStream = new BufferedStream(fs);
for (int i = 0; i <= mlockCount - 1; i++)
{
bufferedStream.Read(mBlockBytes, 0, mBlockBytes.Length);
HashComputing(mBlockBytes);
}
if (lastBlockLength < _paddingByteConst)
{
mBlockBytes = new byte[blockByteLength];
bufferedStream.Read(mBlockBytes, 0, mBlockBytes.Length);
mBlockBytes[(int)(fs.Length) % blockByteLength] = 128;
for (int i = 0; i <= mByteLength.Length - 1; i++)
mBlockBytes[blockByteLength - (i + 1)] = mByteLength[i];
HashComputing(mBlockBytes);
}
else
{
mBlockBytes = new byte[blockByteLength];
bufferedStream.Read(mBlockBytes, 0, mBlockBytes.Length);
mBlockBytes[(int)(fs.Length) % blockByteLength] = 128;
HashComputing(mBlockBytes);
mBlockBytes = new byte[blockByteLength];
for (int i = 0; i <= mByteLength.Length - 1; i++)
mBlockBytes[blockByteLength - (i + 1)] = mByteLength[i];
HashComputing(mBlockBytes);
}
string hash = (h1.ToString("X").PadLeft(16, '0') +
h2.ToString("X").PadLeft(16, '0') +
h3.ToString("X").PadLeft(16, '0') +
h4.ToString("X").PadLeft(16, '0') +
h5.ToString("X").PadLeft(16, '0') +
h6.ToString("X").PadLeft(16, '0') +
h7.ToString("X").PadLeft(16, '0') +
h8.ToString("X").PadLeft(16, '0'));
return hash;
}
private void HashComputing(byte[] mBlock)
{
ulong[] K = {
0x428A2F98D728AE22, 0x7137449123EF65CD, 0xB5C0FBCFEC4D3B2F, 0xE9B5DBA58189DBBC,
0x3956C25BF348B538, 0x59F111F1B605D019, 0x923F82A4AF194F9B, 0xAB1C5ED5DA6D8118,
0xD807AA98A3030242, 0x12835B0145706FBE, 0x243185BE4EE4B28C, 0x550C7DC3D5FFB4E2,
0x72BE5D74F27B896F, 0x80DEB1FE3B1696B1, 0x9BDC06A725C71235, 0xC19BF174CF692694,
0xE49B69C19EF14AD2, 0xEFBE4786384F25E3, 0x0FC19DC68B8CD5B5, 0x240CA1CC77AC9C65,
0x2DE92C6F592B0275, 0x4A7484AA6EA6E483, 0x5CB0A9DCBD41FBD4, 0x76F988DA831153B5,
0x983E5152EE66DFAB, 0xA831C66D2DB43210, 0xB00327C898FB213F, 0xBF597FC7BEEF0EE4,
0xC6E00BF33DA88FC2, 0xD5A79147930AA725, 0x06CA6351E003826F, 0x142929670A0E6E70,
0x27B70A8546D22FFC, 0x2E1B21385C26C926, 0x4D2C6DFC5AC42AED, 0x53380D139D95B3DF,
0x650A73548BAF63DE, 0x766A0ABB3C77B2A8, 0x81C2C92E47EDAEE6, 0x92722C851482353B,
0xA2BFE8A14CF10364, 0xA81A664BBC423001, 0xC24B8B70D0F89791, 0xC76C51A30654BE30,
0xD192E819D6EF5218, 0xD69906245565A910, 0xF40E35855771202A, 0x106AA07032BBD1B8,
0x19A4C116B8D2D0C8, 0x1E376C085141AB53, 0x2748774CDF8EEB99, 0x34B0BCB5E19B48A8,
0x391C0CB3C5C95A63, 0x4ED8AA4AE3418ACB, 0x5B9CCA4F7763E373, 0x682E6FF3D6B2B8A3,
0x748F82EE5DEFB2FC, 0x78A5636F43172F60, 0x84C87814A1F0AB72, 0x8CC702081A6439EC,
0x90BEFFFA23631E28, 0xA4506CEBDE82BDE9, 0xBEF9A3F7B2C67915, 0xC67178F2E372532B,
0xCA273ECEEA26619C, 0xD186B8C721C0C207, 0xEADA7DD6CDE0EB1E, 0xF57D4F7FEE6ED178,
0x06F067AA72176FBA, 0x0A637DC5A2C898A6, 0x113F9804BEF90DAE, 0x1B710B35131C471B,
0x28DB77F523047D84, 0x32CAAB7B40C72493, 0x3C9EBE0A15C9BEBC, 0x431D67C49C100D4C,
0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A, 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817
};
ulong a = h1;
ulong b = h2;
ulong c = h3;
ulong d = h4;
ulong e = h5;
ulong f = h6;
ulong g = h7;
ulong h = h8;
ulong[] w = new ulong[80];
for (int n = 0; n <= 79; n++)
{
if (n <= 15)
{
w[n] = (ulong)mBlock[n * 8] * (ulong)Math.Pow(16.0, 14.0) +
(ulong)mBlock[n * 8 + 1] * (ulong)Math.Pow(16.0, 12.0) +
(ulong)mBlock[n * 8 + 2] * (ulong)Math.Pow(16.0, 10.0) +
(ulong)mBlock[n * 8 + 3] * (ulong)Math.Pow(16.0, 8.0) +
(ulong)mBlock[n * 8 + 4] * (ulong)Math.Pow(16.0, 6.0) +
(ulong)mBlock[n * 8 + 5] * (ulong)Math.Pow(16.0, 4.0) +
(ulong)mBlock[n * 8 + 6] * (ulong)Math.Pow(16.0, 2.0) +
(ulong)mBlock[n * 8 + 7];
}
else
{
ulong p0 = (((w[n - 15]) >> (1)) | ((w[n - 15]) << (64 - (1)))) ^ (((w[n - 15]) >> (8)) | ((w[n - 15]) << (64 - (8)))) ^ (w[n - 15] >> 7);
ulong p1 = (((w[n - 2]) >> (19)) | ((w[n - 2]) << (64 - (19)))) ^ (((w[n - 2]) >> (61)) | ((w[n - 2]) << (64 - (61)))) ^ (w[n - 2] >> 6);
w[n] = (p1 + w[n - 7] + p0 + w[n - 16]);
}
ulong s1 = ((e >> 14) | (e << (64 - 14))) ^ ((e >> 18) | (e << (64 - 18))) ^ ((e >> 41) | (e << (64 - 41)));
ulong ch = (e & f) ^ ((~e) & g);
ulong t1 = h + s1 + ch + K[n] + w[n];
ulong s0 = (((a) >> (28)) | ((a) << (64 - (28)))) ^ (((a) >> (34)) | ((a) << (64 - (34)))) ^ (((a) >> (39)) | ((a) << (64 - (39))));
ulong maj = (a & b) ^ (a & c) ^ (b & c);
ulong t2 = s0 + maj;
h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
h1 += a;
h2 += b;
h3 += c;
h4 += d;
h5 += e;
h6 += f;
h7 += g;
h8 += h;
}
}
}
3. Kaynakça
Toz, D., Balasch, J., & Sheikh, F. (2016). Circuits and Systems for Securityand Privacy. Circuits and Systems for Securityand Privacy (s. 406). içinde CRC Press.
메타데이터
- post_id
- d017bc3d8a78
- slug
- sha-2-kriptografik-özet-fonksiyonu-d017bc3d8a78
- url
- https://medium.com/@abtarim/sha-2-kriptografik-%C3%B6zet-fonksiyonu-d017bc3d8a78
- canonical_url
- https://medium.com/@abtarim/sha-2-kriptografik-%C3%B6zet-fonksiyonu-d017bc3d8a78
- author_url
- https://medium.com/@abtarim
- status
- ok
- fetched_at
- 2026-07-25 14:21:05