21 Ocak 2013 Pazartesi

Rijndael Şifreleme Algoritması


Rijndael Şifreleme Algoritması

Galois’in alan teorisi üzerine kurulu olan Rijndael, DES gibi yer değiştirme ve permütasyon tekniklerini bir çok defa kullanarak şifrelemeyi gerçekleştiren bir şifreleme algoritmasıdır. Bu yazımızda Microsoft .NET teknolojileri ile Rijndael algoritmasının nasıl gerçekleşebileceğimizi inceleyeceğiz.

Galois’in alan teorisi üzerine kurulu olan Rijndael, DES gibi yer değiştirme ve permütasyon tekniklerini bir çok defa kullanarak şifrelemeyi gerçekleştirmektedir. Kaç sefer bu yer değiştirme ve permütasyon tekniklerinin tekrarlanacağı anahtar ve blok boyutuna bağlıdır. Örneğin, 128 bitlik anahtar ve 128 bitlik blok boyutları ile yapılacak şifreleme için bu tekrar sayısı 10’dur. DES’ten farklı olarak donanım ve yazılım olarak yapılmasının kolay olması için bütün işlemler tüm byte’ları kullanmaktadır(Geri besleme boyutu blok boyutuna eşittir). Bu algoritma oldukça hızlı çalışması yönüyle tercih edilmektedir.

Microsoft .NET Framework’ te System.Security.Cryptography altında yer alan Rijndael soyut sınıfı Rijndael algoritmasını gerçeklemek isteyen sınıflar için ana sınıfı tanımlar. Rijndael sınıfında yer alan erişilebilir özellikleri şunlardır:
  • BlockSize, kriptografik işlemler için kullanılacak olan blok boyutunu bit olarak belirtir. Varsayılan değeri 128 bittir.
  • FeedbackSize, kriptografik işlemin geri besleme boyutunu bit olarak ifade eder, varsayılan değeri 128 bittir.
  • IV, Rijndael algoritmasının ilk vektörünü (Initial Vector) ifade eder.
  • Key, Rijndael algoritması tarafından kullanılan anahtarı ifade eder.
  • KeySize, Rijndael algoritması tarafından kullanılan gizli anahtarın boyutunu bit olarak belirtir. Varsayılan değeri 256 bittir.
  • LegalBlockSizes, Rijndael tarafından desteklenen blok boyutlarının sınırını bit olarak ifade eder. En az 128 ve en çok değeri 256 bittir.
  • LegalKeySizes, Rijndael tarafından desteklenen anahtar boyutlarının sınırını bit olarak ifade eder. Rijndael için en az 128 bit ve en çok 256 bittir.
  • Mode, Rijndael’in hangi mod ile şifreleme yapacağını gösterir.
  • Padding, Rijndael algoritması tarafından kullanılacak olan doldurma modunu ifade eder.
Bu sınıfın erişilebilir metotları ise şunlardır:
  • Clear, Rijndael algoritması tarafından kullanılan tüm kaynakları sisteme geri verir.
  • Create, Rijndael algoritmasını gerçekleştirecek bir nesne oluşturur.
  • CreateDecryptor, Rijndael deşifreleyicisi oluşturur.
  • CreateEncryptor, Rijndael şifreleyicisi oluşturur.
  • Equals, iki nesnenin birbirine eşit olup olmadığını test eder.
  • GenerateIV, Rijndael algoritması tarafından kullanılacak rastgele bir ilk vektör değeri oluşturur.
  • GenerateKey, Rijndael algoritması tarafından kullanılacak rastgele bir anahtar oluşturur.
  • GetHashCode, bellekteki o nesneye özgü bir hash kodu oluşturur.
  • GetType, bu nesnenin tipini verir.
  • ToString, şu an ki nesneyi ifade eden bir metin oluşturur.
  • ValidKeySize, bu algoritma için belirtilen anahtar boyutunun geçerli olup olmadığını test eder.
RijndaelManaged, standart Rijndael algoritmasını gerçekleyen, Rijndael sınıfından türeyen mühürlü bir sınıftır. Mühürlü sınıf, hiç bir sınıfın kendisinden türetilemeyeceğini ifade eder. Bu sınıfın erişilebilir özellikleri şunlardır:
  • BlockSize, kriptografik işlemler için kullanılacak olan blok boyutunu bit olarak belirtir. Varsayılan değeri 128 bittir.
  • FeedbackSize, kriptografik işlemin geri besleme boyutunu bit olarak ifade eder, varsayılan değeri 128 bittir.
  • IV, Rijndael algoritmasının ilk vektörünü (Initial Vector) ifade eder.
  • Key, Rijndael algoritması tarafından kullanılan anahtarı ifade eder.
  • KeySize, Rijndael algoritması tarafından kullanılan gizli anahtarın boyutunu bit olarak belirtir. Varsayılan değeri 256 bittir.
  • LegalBlockSizes, Rijndael tarafından desteklenen blok boyutlarının sınırını bit olarak ifade eder. Rijndael algoritması tarafından desteklenen blok boyutu en az 128 ve en çok değeri 256 bittir.
  • LegalKeySizes, Rijndael tarafından desteklenen anahtar boyutlarının sınırını bit olarak ifade eder. Rijndael için en az 128 bit ve en çok 256 bittir.
  • Mode, Rijndael’in hangi mod ile şifreleme yapacağını gösterir.
  • Padding, Rijndael algoritması tarafından kullanılacak olan doldurma modunu ifade eder.
Bu sınıfın erişilebilir metotları ise şunlardır:
  • Clear, Rijndael algoritması tarafından kullanılan tüm kaynakları sisteme geri verir.
  • Create, Rijndael algoritmasını gerçekleştirecek bir nesne oluşturur.
  • CreateDecryptor, Rijndael deşifreleyicisi oluşturur.
  • CreateEncryptor, Rijndael şifreleyicisi oluşturur.
  • Equals, iki nesnenin birbirine eşit olup olmadığını test eder.
  • GenerateIV, Rijndael algoritması tarafından kullanılacak rastgele bir ilk vektör değeri oluşturur.
  • GenerateKey, Rijndael algoritması tarafından kullanılacak rastgele bir anahtar oluşturur.
  • GetHashCode, bellekteki o nesneye özgü bir hash kodu oluşturur.
  • GetType, bu nesnenin tipini verir.
  • ToString, şu an ki nesneyi ifade eden bir metin oluşturur.
  • ValidKeySize, bu algoritma için belirtilen anahtar boyutunun geçerli olup olmadığını test eder.
Bu sınıfın kullanımını daha iyi anlayabilmek için örnek bir sınıf hazırlayalım. Şifreleme ve deşifreleme işlemlerini yapan bir web servisi geliştirmek de mümkündür. Ancak her algoritmada olabildiğince farklı örnekler vererek Microsoft .NET teknolojileriyle uygulama geliştirmenin getirdiği yöntem zenginliğine dikkat çekmek istiyorum.

C#
using System.Text;
using System.IO;
using System.Security.Cryptography;
 
namespace CryptographyServicesCS
{
    public class RijndaelCipher
    {
        private RijndaelManaged rm = new RijndaelManaged();
        public RijndaelCipher()
        {
            rm.GenerateIV();
            rm.GenerateKey();
        }
 
        public byte[] EncryptString(string stringToEncrypt)
        {
            MemoryStream ms = new MemoryStream();
            CryptoStream encStream;
            try
            {
                byte[] buffer = Encoding.UTF8.GetBytes(stringToEncrypt);
                encStream = new CryptoStream(ms,
                rm.CreateEncryptor(rm.Key,rm.IV),CryptoStreamMode.Write);
                encStream.Write(buffer,0,buffer.Length);
                encStream.Close();
                return ms.ToArray();
            }
            finally
            {
                ms.Close();
            }
        }
 
        public string DecryptString(byte[] buffer)
        {
            MemoryStream ms = new MemoryStream();
            CryptoStream decStream;
            try
            {
                decStream = new CryptoStream(ms,
                rm.CreateDecryptor(rm.Key,rm.IV),CryptoStreamMode.Write);
                decStream.Write(buffer,0,buffer.Length);
                decStream.Close();
                return Encoding.UTF8.GetString(ms.ToArray());
            }
            finally
            {
                ms.Close();
            }
        }
    }
}
VB.NET
Imports System.Text
Imports System.Security.Cryptography
Imports System.IO
 
Public Class RijndaelCipher
    Private rm As New RijndaelManaged
    Public Sub New()
        rm.GenerateIV()
        rm.GenerateKey()
    End Sub
    Public Function EncryptString(ByVal stringToEncrypt As String) As Byte()
        Dim ms As New MemoryStream
        Dim encStream As CryptoStream
        Try
            Dim buffer As Byte() = Encoding.UTF8.GetBytes(stringToEncrypt)
            encStream = New CryptoStream(ms, 
            rm.CreateEncryptor(rm.Key, rm.IV), CryptoStreamMode.Write)
            encStream.Write(buffer, 0, buffer.Length)
            encStream.Close()
            Return ms.ToArray()
        Finally
            ms.Close()
        End Try
    End Function
    Public Function DecryptString(ByVal buffer As Byte()) As String
        Dim ms As New MemoryStream
        Dim decStream As CryptoStream
        Try
            decStream = New CryptoStream(ms, 
            rm.CreateDecryptor(rm.Key, rm.IV), CryptoStreamMode.Write)
            decStream.Write(buffer, 0, buffer.Length)
            decStream.Close()
            Return Encoding.UTF8.GetString(ms.ToArray())
        Finally
            ms.Close()
        End Try
    End Function
End Class
C++.NET
#pragma once
using namespace System;
using namespace System::IO;
using namespace System::Text;
using namespace System::Security::Cryptography;
 
namespace CryptographyServicesCPP
{
    public __gc class RijndaelCipher
    {
    private:
        RijndaelManaged __gc* rm;
    public:
        RijndaelCipher()
        {
            rm= __gc new RijndaelManaged();
            rm->GenerateIV();
            rm->GenerateKey();
        }
        Byte EncryptString(String __gc* stringToEncrypt)[]
        {
            MemoryStream __gc* ms = __gc new MemoryStream();
            CryptoStream __gc* encStream;
            Byte buffer[];
            __try
            {
                int byteCount= Encoding::UTF8->GetByteCount(stringToEncrypt);
                buffer = new Byte[byteCount];
                Encoding::UTF8->GetBytes(stringToEncrypt,0,
                stringToEncrypt->Length,buffer,0);
                encStream = __gc new CryptoStream(ms,
                rm->CreateEncryptor(rm->Key,rm->IV),CryptoStreamMode::Write);
                encStream->Write(buffer,0,byteCount);
                encStream->Close();
                return ms->ToArray();
            }
            __finally
            {
                ms->Close();
            }
        }
        System::String* DecryptString(Byte buffer[])
        {
            MemoryStream __gc* ms = __gc new MemoryStream();
            CryptoStream __gc* decStream;
            __try
            {
                decStream = __gc new CryptoStream(ms,
                rm->CreateDecryptor(rm->Key,rm->IV),
                CryptoStreamMode::Write);
                decStream->Write(buffer,0,buffer->Count);
                decStream->Close();
                return Encoding::UTF8->GetString(ms->ToArray());
            }
            __finally
            {
                ms->Close();
            }
        }
 
    };
}
J#
package CryptographyServicesJS;
 
import System.Text.*;
import System.IO.*;
import System.Security.Cryptography.*;
 
 
public class RijndaelCipher
{
    private RijndaelManaged rm = new RijndaelManaged();
         public RijndaelCipher()
         {
        rm.GenerateIV();
        rm.GenerateKey();
         }
    public ubyte[] EncryptString(String stringToEncrypt)
    {
        MemoryStream ms = new MemoryStream();
        CryptoStream encStream;
        try
        {
            ubyte[] buffer = Encoding.get_UTF8().GetBytes(stringToEncrypt);
            encStream = new CryptoStream(ms,
            rm.CreateEncryptor(rm.get_Key(),rm.get_IV()),
            CryptoStreamMode.Write);
            encStream.Write(buffer,0,buffer.length);
            encStream.Close();
            return ms.ToArray();
        }
        finally
        {
            ms.Close();
        }
    }
 
    public String DecryptString(ubyte[] buffer)
    {
        MemoryStream ms = new MemoryStream();
        CryptoStream encStream;
        try
        {
            encStream = new CryptoStream(ms,
            rm.CreateDecryptor(rm.get_Key(),rm.get_IV()),
            CryptoStreamMode.Write);
            encStream.Write(buffer,0,buffer.length);
            encStream.Close();
            return Encoding.get_UTF8().GetString( ms.ToArray() );
        }
        finally
        {
            ms.Close();
        }
    }
}
Son Söz:
Çok karışık bir algoritmaya sahip olmasına karşın Rijndael ile şifreleme yapabilmeniz için bu makaleyi okumanız yeterli olacaktır. Microsoft .NET ile sağlananan en önemli özellik de zaten budur; uygulama geliştiriciyi gereksiz detaylarla uğraştırmamaktır. Bu sayede daha büyük projelere imza atabilirsiniz. Bir sonraki makalemizde görüşünceye kadar güvende kalın...
İlgili Makaleler:

Referanslar:

Yazar : Yunus Emre ALPÖZEN
e-Posta : yemre@msakademik.net

Hiç yorum yok:

Yorum Gönder

isterseniz anonim seçeneginden kayıtsız gönderebilirsiniz iyi günler