Zaciemnianie danych i kodu źródłowego oraz kryptografia symetryczna – jak to zrobić kodem prostych narzędzi skryptowych

Zaciemnianie (obfuskacja) danych czy kodu źródłowego programów jest techniką zabezpieczeń z kategorii security by obscurity i stosuje się ją w celu utrudnienia, a nie całkowitego uniemożliwienia odczytania danych czy też przeprowadzenia analizy kodu.  Szyfrowanie dla odmiany służy skutecznej ochronie poufności informacji.  Moim celem nie jest tworzenie monografii poświęconej jednemu czy też drugiemu z wymienionych tematów. Pochłonęłyby wiele tomów i kawał mojego życia🙂. Bardziej interesują mnie one z punktu widzenia możliwości szybkiego opracowania zupełnie darmowych narzędzi pomagających w praktyce realizować te ważne funkcje.

052213_1731_DataExfiltr33W tym celu napisałem skrypt, który pozwala na zaciemnianie dowolnych danych tekstowych z wykorzystaniem algorytmów ROT-13 lub ROT-47 albo Base64. Lista algorytmów nie jest zamknięta, a skrypt jest swego rodzaju otwartym środowiskiem, które możemy, przez prostą modyfikację kodu, łatwo wzbogacić o nowe funkcje zaciemniające, bądź to „gotowe”, bądź też całkowicie autorskie.

Skrypt integruje funkcje obfuskacji i deobfuskacji z kryptografią symetryczną. Możemy zatem przy jego pomocy, oprócz zaciemnienia, dowolny tekst poddać szyfrowaniu takimi algorytmami jak 3DES, AES-256, Blowfish czy Camelia. Tu znowu warto podkreślić, że lista algorytmów szyfrujących nie jest zamknięta i przez bardzo prostą modyfikację kodu możemy napisać dodatkowe funkcje szyfrujące i deszyfrujące, implementujące inne algorytmy kryptograficzne.

Łączenie w jednym narzędziu takich funkcji, jak obfuskacja, deobfuskacja, szyfrowanie i deszyfrowanie, pozwala ze skryptu czynić całkiem niezły użytek. Ufam, że narzędzie stanie się jeszcze bardziej użyteczne po jego zmodyfikowaniu i wprowadzeniu dalszych udoskonaleń.

W jakim kierunku, poza wcześniej wspomnianym rozszerzeniem listy funkcji zaciemniających i algorytmów kryptograficznych, skrypt może być dalej rozwijany? Podam przykłady, jako pierwsze przychodzące mi do głowy:

  • Zaciemnianie plików
  • Anonimizacja danych
  • Parametryzacja funkcji zaciemniających oparta o globbing lub wyrażenia regularne

To tylko trzy podpowiedzi. Wierzę, że moi Czytelnicy wymyślą ich więcej, do czego serdecznie – jak zwykle – Was namawiam.

Skrypt posiada graficzny interfejs użytkownika napisany w oparciu o bibliotekę Tk. Podstawowe jego funkcjonalności są dostępne poprzez interfejs graficznych zakładek. Poniżej przedstawiam zrzuty ekranowe interfejsu, odpowiadające funkcjonalnościom szyfrowania, deszyfrowania i zaciemniania.

Szyfrowanie:

encryption

Deszyfrowanie:

decryption

Zaciemnianie:

obfuscation

Oto kod skryptu:

require 'tk'
require 'tkextlib/tile'
require 'Base64'
require 'openssl'
require 'digest/sha1'

def alert(tekst)
   Tk::messageBox :message => "#{tekst}"
end

def rot13_encode(string)
   return string.tr("a-z", "n-za-m")
end

def mrot13_encode(string)
   return string.tr("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM", \
                    "djreglhvbcnfqstuwxymkpioazDJREGLHVBCNFQSTUWXYMKPIOAZ")
end

def rot47_encode(string)
   return string.tr("\x21-\x7e", "\x50-\x7e\x21-\x4f")
end

def base64_encoding(string)
   return Base64.encode64(string)
end

def output_coding(operation, input_text)
   case operation
      when "encode"
         result = Base64.encode64(input_text)
      when "decode"
         result = Base64.decode64(input_text)
      else 
         result "Unknown operation: must be encode or decode"
   end
   return result
end

def obfuscate(algorithm, plaintext)
   case algorithm
      when "rot13"
         result = rot13_encode(plaintext)
      when "mrot13"
         result = mrot13_encode(plaintext)
      when "rot47"
         result = rot47_encode(plaintext)
      when "base64"
         result = base64_encoding(plaintext)
      else
         result = "Error in obfuscation: no such method"
   end
   return result
end

def encrypt(alg, kee, plaintext)
   case alg
      when 'des3'
        crypto = "des3" 
      when 'aes'
         crypto = "aes-256-cbc" 
      when 'camelia'
         crypto = "camellia-256-ecb" 
      when 'blowfish'
         crypto = "bf" 
   end
   begin
      cipher = OpenSSL::Cipher::Cipher.new(crypto)
      cipher.encrypt
      cipher.key = key = Digest::SHA1.hexdigest(kee)
      ciphertext = cipher.update(plaintext)
      ciphertext << cipher.final       
      ciphertext = Base64.encode64(ciphertext)    
   rescue => e 
      alert("Problem with encryption\n#{e.message}")
      return
   end 
   return ciphertext
end

def decrypt(alg, kee, ciphertext)
   case alg
      when 'des3'
         crypto = "des3" 
      when 'aes'
         crypto = "aes-256-cbc" 
      when 'camelia'
         crypto = "camellia-256-ecb" 
      when 'blowfish'
         crypto = "bf" 
   end
   begin
      ciphertext = Base64.decode64(ciphertext)
      cipher = OpenSSL::Cipher::Cipher.new(crypto)
      cipher.decrypt
      cipher.key = key = Digest::SHA1.hexdigest(kee)
      plaintext = cipher.update(ciphertext)
      plaintext << cipher.final    
   rescue => e 
      alert("Problem with decryption\n#{e.message}")
      return
   end
   return plaintext
end

# ------------------- Main program --------------------

root = TkRoot.new { resizable 0, 0 }
root.title = "Encryptor&Decryptor&Obfuscator - Janusz Nawrat - 2014"

n = Tk::Tile::Notebook.new(root) do
  pack()
end

f1 = TkFrame.new(n)
f2 = TkFrame.new(n)
f3 = TkFrame.new(n)

button_frame = TkFrame.new(root, :borderwidth => 3, :padx => 5, :pady => 5).pack(:side => 'top', :fill => 'x')
exit_button = TkButton.new(button_frame, :text => "Exit", :width => 15, :pady => 5, :command => 'exit').pack()

n.add f1, :text => 'Encryption'
n.add f2, :text => 'Decryption'
n.add f3, :text => 'Obfuscation'

# ------------------------------------- Code block for encryption ---------------------------------------

input_frame = TkFrame.new(f1, :relief => "sunken", :borderwidth => 3, :padx => 5, :pady => 5).pack(:side => 'top')

input_label = TkLabel.new(input_frame, :text => "Clear text").pack(:fill => 'both', :side => 'top')

clear_text = TkText.new(input_frame) {
   width 60
   height 10
   borderwidth 1
   font TkFont.new('courier 10')
   pack(:side => "left", :padx=> 5, :pady => 5)
}

inp_v_scroll_bar = TkScrollbar.new(input_frame, :orient => 'vertical', :command => proc { |*args| clear_text.yview *args })
inp_v_scroll_bar.pack(:side => 'left', :fill => 'y')
clear_text.yscrollcommand(proc { |first,last| inp_v_scroll_bar.set(first,last) })

option_frame = TkFrame.new(f1, :borderwidth => 3, :padx => 5, :pady => 5).pack(:side => 'top')
option_label = TkLabel.new(option_frame, :text => "Crypto algorithm: ").pack(:side => 'left')

$alg_encr = TkVariable.new
$alg_encr.value = "aes"

TkRadiobutton.new(option_frame) do
   text "3DES"
   variable $alg_encr
   value "des3"
   anchor 'w'
   pack(:side => 'left')
end

TkRadiobutton.new(option_frame) do
   text "AES-256"
   variable $alg_encr
   value "aes"
   anchor 'w'
   pack(:side => 'left')
end

TkRadiobutton.new(option_frame) do
   text "Blowfish"
   variable $alg_encr
   value "blowfish"
   anchor 'w'
   pack(:side => 'left')
end

TkRadiobutton.new(option_frame) do
   text "Camelia"
   variable $alg_encr
   value "camelia"
   anchor 'w'
   pack(:side => 'left')
end

$encrypt_key = TkVariable.new
$encrypt_key.value = "$ecYouR3"

crypto_key_frame = TkFrame.new(f1, :relief => "sunken", :borderwidth => 3, :padx => 5, :pady => 5).pack(:side => 'top', :fill => 'x')
encrypt_key_label = TkLabel.new(crypto_key_frame, :text => "Encryption key: ").pack(:side => 'left')
encrypt_key_entry = TkEntry.new(crypto_key_frame, :width => 40, :textvariable => $encrypt_key).pack(:side => 'left')

output_frame = TkFrame.new(f1, :relief => "sunken", :borderwidth => 3, :padx => 5, :pady => 5).pack(:side => 'top')

output_label = TkLabel.new(output_frame, :text => "Cipher text").pack(:fill => 'both', :side => 'top')

cipher_text = TkText.new(output_frame) {
   width 60
   height 10
   borderwidth 1
   font TkFont.new('courier 10')
   pack(:side => "left",  :padx=> 5, :pady => 5)
}

out_v_scroll_bar = TkScrollbar.new(output_frame, :orient => 'vertical', :command => proc { |*args| cipher_text.yview *args })
out_v_scroll_bar.pack(:side => 'left', :fill => 'y')
cipher_text.yscrollcommand(proc { |first,last| out_v_scroll_bar.set(first,last) })

button_frame = TkFrame.new(f1) do
   pack(:side => 'top')
end

go_button = TkButton.new(button_frame) do
   text "Encrypt"
   width 15
   command proc { buffer = clear_text.get("1.0", "end"); cipher_text.insert("end", encrypt($alg_encr.value, $encrypt_key.value, buffer)) }
   pack(:side => 'left', :padx => 2, :pady => 5)
end

clear_button = TkButton.new(button_frame) do
   text "Clear"
   width 15
   command {clear_text.delete("1.0", 'end'); cipher_text.delete("1.0", 'end')}
   pack(:side => 'left', :padx => 2, :pady => 5)
end

puts root.geometry

# ------------------------------------- Code block for decryption ---------------------------------------

input_frame = TkFrame.new(f2, :relief => "sunken", :borderwidth => 3, :padx => 5, :pady => 5).pack(:side => 'top')

input_label = TkLabel.new(input_frame, :text => "Cipher text").pack(:fill => 'both', :side => 'top')

encr_text = TkText.new(input_frame) {
   width 60
   height 10
   borderwidth 1
   font TkFont.new('courier 10')
   pack(:side => "left", :padx=> 5, :pady => 5)
}

inp_v_scroll_bar = TkScrollbar.new(input_frame, :orient => 'vertical', :command => proc { |*args| encr_text.yview *args })
inp_v_scroll_bar.pack(:side => 'left', :fill => 'y')
encr_text.yscrollcommand(proc { |first,last| inp_v_scroll_bar.set(first,last) })

option_frame = TkFrame.new(f2, :borderwidth => 3, :padx => 5, :pady => 5).pack(:side => 'top')
option_label = TkLabel.new(option_frame, :text => "Crypto algorithm: ").pack(:side => 'left')

$alg_decr = TkVariable.new
$alg_decr.value = "aes"

TkRadiobutton.new(option_frame) do
   text "3DES"
   variable $alg_decr
   value "des3"
   anchor 'w'
   pack(:side => 'left')
end

TkRadiobutton.new(option_frame) do
   text "AES-256"
   variable $alg_decr
   value "aes"
   anchor 'w'
   pack(:side => 'left')
end

TkRadiobutton.new(option_frame) do
   text "Blowfish"
   variable $alg_decr
   value "blowfish"
   anchor 'w'
   pack(:side => 'left')
end

TkRadiobutton.new(option_frame) do
   text "Camelia"
   variable $alg_decr
   value "camelia"
   anchor 'w'
   pack(:side => 'left')
end

$decrypt_key = TkVariable.new
$decrypt_key.value = "$ecYouR3"

decrypto_key_frame = TkFrame.new(f2, :relief => "sunken", :borderwidth => 3, :padx => 5, :pady => 5).pack(:side => 'top', :fill => 'x')
decrypt_key_label = TkLabel.new(decrypto_key_frame, :text => "Decryption key: ").pack(:side => 'left')
decrypt_key_entry = TkEntry.new(decrypto_key_frame, :width => 40, :textvariable => $decrypt_key).pack(:side => 'left')

output_frame = TkFrame.new(f2, :relief => "sunken", :borderwidth => 3, :padx => 5, :pady => 5).pack(:side => 'top')

output_label = TkLabel.new(output_frame, :text => "Clear text").pack(:fill => 'both', :side => 'top')

decr_text = TkText.new(output_frame) {
   width 60
   height 10
   borderwidth 1
   font TkFont.new('courier 10')
   pack(:side => "left", :padx=> 5, :pady => 5)
}

out_v_scroll_bar = TkScrollbar.new(output_frame, :orient => 'vertical', :command => proc { |*args| decr_text.yview *args })
out_v_scroll_bar.pack(:side => 'left', :fill => 'y')
decr_text.yscrollcommand(proc { |first,last| out_v_scroll_bar.set(first,last) })

button_frame = TkFrame.new(f2) do
   pack(:side => 'top')
end

go_button = TkButton.new(button_frame) do
   text "Decrypt"
   width 15
	
   #  buffer = encr_text.get("1.0", "end"); decr_text.insert("end", encrypt($alg_decr.value, "kluczyk", buffer)) 
	
   command proc { buffer = encr_text.get("1.0", "end"); decr_text.insert("end", decrypt($alg_decr.value, $decrypt_key.value, buffer)) }
   pack(:side => 'left', :padx => 2, :pady => 5)
end

clear_button = TkButton.new(button_frame) do
   text "Clear"
   width 15
   command {encr_text.delete("1.0", 'end'); decr_text.delete("1.0", 'end')}
   pack(:side => 'left', :padx => 2, :pady => 5)
end

# ------------------------------------- Code block for obfuscation --------------------------------------

input_frame = TkFrame.new(f3, :relief => "sunken", :borderwidth => 3, :padx => 5, :pady => 5).pack(:side => 'top')

input_label = TkLabel.new(input_frame, :text => "Input text").pack(:fill => 'both', :side => 'top')

input_text = TkText.new(input_frame) {
   width 60
   height 10
   borderwidth 1
   font TkFont.new('courier 10')
   pack(:side => "left", :padx=> 5, :pady => 5)
}

inp_v_scroll_bar = TkScrollbar.new(input_frame, :orient => 'vertical', :command => proc { |*args| input_text.yview *args })
inp_v_scroll_bar.pack(:side => 'left', :fill => 'y')
input_text.yscrollcommand(proc { |first,last| inp_v_scroll_bar.set(first,last) })

option_frame = TkFrame.new(f3, :borderwidth => 3, :padx => 5, :pady => 5).pack(:side => 'top')
option_label = TkLabel.new(option_frame, :text => "Obfuscation method: ").pack(:side => 'left')

$alg = TkVariable.new
$alg.value = "mrot13"

TkRadiobutton.new(option_frame) do
   text "ROT-13"
   variable $alg
   value "rot13"
   anchor 'w'
   pack(:side => 'left')
end

TkRadiobutton.new(option_frame) do
   text "ROT-47"
   variable $alg
   value "rot47"
   anchor 'w'
   pack(:side => 'left')
end

TkRadiobutton.new(option_frame) do
   text "Modified ROT-13"
   variable $alg
   value "mrot13"
   anchor 'w'
   pack(:side => 'left')
end

TkRadiobutton.new(option_frame) do
   text "Base64"
   variable $alg
   value "base64"
   anchor 'w'
   pack(:side => 'left')
end

output_frame = TkFrame.new(f3, :relief => "sunken", :borderwidth => 3, :padx => 5, :pady => 5).pack(:side => 'top')

output_label = TkLabel.new(output_frame, :text => "Output text").pack(:fill => 'both', :side => 'top')

output_text = TkText.new(output_frame) {
   width 60
   height 10
   borderwidth 1
   font TkFont.new('courier 10')
   pack(:side => "left",  :padx=> 5, :pady => 5)
}

output_text.pack(:side => "left",  :padx=> 5, :pady => 5)

out_v_scroll_bar = TkScrollbar.new(output_frame, :orient => 'vertical', :command => proc { |*args| output_text.yview *args })
out_v_scroll_bar.pack(:side => 'left', :fill => 'y')
output_text.yscrollcommand(proc { |first,last| out_v_scroll_bar.set(first,last) })

$encoding = TkVariable.new
$encoding.value = "decode"

button_frame = TkFrame.new(f3) do
   pack(:side => 'top')
end

space_label = TkLabel.new(button_frame, :text => " " * 25)

encoding_button = TkCheckButton.new(button_frame) do
   text "Output Base64 encoding"
   variable $encoding
   onvalue "encode"
   offvalue "decode"
   command {buffer = output_text.get("1.0", "end"); output_text.delete("1.0", "end"); output_text.insert("1.0", output_coding($encoding.value, buffer))}
   pack(:side => "left")
end

space_label.pack(:side => 'left')

go_button = TkButton.new(button_frame) do
   text "Obfuscate"
   width 15
   command proc { output_text.insert("end", obfuscate($alg.value, input_text.get("1.0", "end"))) }
   pack(:side => 'left', :padx => 2, :pady => 5)
end

clear_button = TkButton.new(button_frame) do
   text "Clear"
   width 15
   command {input_text.delete("1.0", 'end'); output_text.delete("1.0", 'end')}
   pack(:side => 'left', :padx => 2, :pady => 5)
end

Tk.mainloop

Informacje Janusz Nawrat
Just ordinary man who likes thinking...

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Log Out / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Log Out / Zmień )

Facebook photo

Komentujesz korzystając z konta Facebook. Log Out / Zmień )

Google+ photo

Komentujesz korzystając z konta Google+. Log Out / Zmień )

Connecting to %s

TOMASZ WEŁNA

artysta grafik | wykładowca

PRACOWNIA OKO

Szkoła Rysunku Malarstwa i Grafiki DR TOMASZA WEŁNY | KRAKÓW | Plac Matejki 10 | tel 691 81 75 74

Piękno neurobiologii

Blog Jerzego Vetulaniego

Teoria muzyki, zasady muzyki, podstawy muzyki

Teoria muzyki, zasady muzyki, podstawy muzyki - czyli to co każdy amator muzyki wiedzieć powinien :)

Personal Development & Inspirations

Przemyślenia i refleksje, którymi warto się podzielić (blog by Janusz Nawrat)

Business IT Cooperation Platform

Biznes i IT - dwa światy, które muszą współdziałać

%d bloggers like this: