id
oleh
PRASETYO BAWONO
M0103045
SKRIPSI
Ditulis dan diajukan untuk memenuhi sebagian persyaratan
Memperoleh gelar Sarjana Sains Matematika
SKRIPSI
TEKNIK PENGAMANAN DATA
MENGGUNAKAN ALGORITMA BLOWFISH
yang disiapkan dan disusun oleh
PRASETYO BAWONO
NIM. M0103045
dibimbing oleh
Pembimbing I, Pembimbing II,
Disahkan oleh
Fakultas Matematika dan Ilmu Pengetahuan Alam
Dekan, Ketua Jurusan Matematika
ABSTRAK
Kata kunci : sistem enkripsi data, algoritma kunci simetri, mode enkripsi cipher
blok, Blowfish, kriptografi
ABSTRACT
KATA PENGANTAR
1. Drs. YS. Palgunadi, M.Sc, selaku pembimbing I dan Drs. Siswanto, M.Si,
selaku pembimbing II yang telah meluangkan waktunya untuk membimbing,
mengarahkan, dan memberikan motivasi kepada penulis dalam penyusunan
skripsi ini.
2. Umi Salamah, S.Si, M.Kom, selaku dosen pembimbing akademik atas segala
kesabarannya selama ini.
3. Drs. Sutrimo, M.Si, selaku Ketua Jurusan Matematika, Fakultas Matematika
dan Ilmu Pengetahuan Alam, Universitas Sebelas Maret.
4. Prof. Drs. Sutarno, M.Sc, Ph.D, selaku Dekan Fakultas Matematika dan Ilmu
Pengetahuan Alam, Universitas Sebelas Maret.
5. Ibunda, Ayahanda, kakak-kakakku, adikku, dan seluruh keluarga yang telah
mendoakan, dan banyak memberikan bantuan, serta dukungan kepada penulis.
6. DR. Sutanto, DEA., selaku kepala UPT PUSKOM UNS, yang telah
menyediakan berbagai fasilitas kepada penulis.
7. Titin Sri Martini, S.Si, M.Kom dan Bowo Winarno, S.Si, M.Kom selaku
dosen penguji.
8. Rekan-rekan di UPT PUSKOM UNS dan di PT. Javatechno Mandiri
Indonesia, atas motivasi, dukungan dan bantuannya selama ini.
Penulis menyadari bahwa skripsi ini masih jauh dari sempurna, untuk itu saran
dan kritik yang bersifat membangun sangat diharapkan. Akhirnya semoga karya
tulis ini dapat bermanfaat bagi pembaca dan dapat memberikan sumbangan
kebaikan pada perkembangan peradaban ilmu pengetahuan dan teknologi
informasi.
Wassalamu’alaikum Warahmatullahi Wabarokatuh.
Penulis
DAFTAR ISI
Halaman
HALAMAN JUDUL .................................................................................. i
PENGESAHAN .......................................................................................... ii
ABSTRAK ................................................................................................. iii
ABSTRACT ............................................................................................... iv
KATA PENGANTAR ............................................................................... v
DAFTAR ISI .............................................................................................. vii
DAFTAR GAMBAR .................................................................................. ix
DAFTAR TABEL ...................................................................................... x
DAFTAR LAMPIRAN .............................................................................. xi
BAB I. PENDAHULUAN
1.1 Latar Belakang Masalah ............................................................. 1
1.2 Perumusan Masalah .................................................................... 2
1.3 Batasan Masalah.......................................................................... 2
1.4 Tujuan Penelitian ....................................................................... 2
1.5 Manfaat Penelitian ..................................................................... 3
BAB II. LANDASAN TEORI
2.1 Tinjauan Pustaka ........................................................................ 4
2.1.1 Algoritma ....................................................................... 4
2.1.2 Lambang Diagram Alir (Flowchart) .............................. 4
2.1.3 Keamanan Data .............................................................. 4
2.1.4 Kriptografi ...................................................................... 6
2.1.5 Cipher Blok .................................................................... 10
2.1.6 Cipher Berulang ............................................................. 12
2.1.7 Jaringan Feistel (Feistel Network) ................................. 12
2.1.8 Kotak-S (S-Box) ............................................................. 13
2.1.9 Algoritma Kriptografi Blowfish ..................................... 14
2.1.10 Mode Operasi Enkripsi Cipher Blok .............................. 17
2.2 Kerangka Pemikiran ................................................................... 23
DAFTAR GAMBAR
Halaman
Gambar 2.1 Simbol Umum Flowchart ..................................................... 4
Gambar 2.2 Skema Enkripsi dan Dekripsi ............................................... 8
Gambar 2.3 Skema Tipe-tipe Cipher ........................................................ 9
Gambar 2.4 Kriptologi, Kriptografi dan Kriptanalisis.................................... 10
Gambar 2.5 Enkripsi Pada Cipher Blok ................................................... 11
Gambar 2.6 Dekripsi Pada Cipher Blok ................................................... 11
Gambar 2.7 Skema Jaringan Feistel Secara Umum ................................. 13
Gambar 2.8 Skema Fungsi F pada algoritma Blowfish ............................ 16
Gambar 2.9 Skema Enkripsi dan Dekripsi dengan Mode ECB ............... 18
Gambar 2.10 Skema Enkripsi dan Dekripsi dengan Mode CBC ............... 20
Gambar 2.11 Skema Enkripsi dan Dekripsi dengan Mode CFB 8-Bit ...... 21
Gambar 2.12 Skema Enkripsi dan Dekripsi dengan Mode OFB 8-bit ...... 23
Gambar 4.1 Alur Sistem Pengamanan Data Teks .................................... 26
Gambar 4.2 Diagram Alir Aplikasi Sistem Pengamanan Data Teks ....... 27
Gambar 4.3 Rancangan Form Sistem Login ............................................ 28
Gambar 4.4 Rancangan Form Sistem Enkripsi ........................................ 29
Gambar 4.5 Rancangan Form Sistem Dekripsi ........................................ 30
Gambar 4.6 Tampilan Form Login .......................................................... 31
Gambar 4.7 Tampilan Form Utama ......................................................... 32
Gambar 4.8 Tampilan Form Enkripsi ...................................................... 33
Gambar 4.9 Pesan Pemberitahuan Enkripsi yang Berhasil ...................... 33
Gambar 4.10 Pesan Peringatan Kesalahan Input Kunci ............................. 34
Gambar 4.11 Dialog Simpan Cipherteks Berekstensi .cip .......................... 34
Gambar 4.12 Pesan Konfirmasi Cipherteks Berhasil Disimpan ................ 35
Gambar 4.13 Tampilan Form Dekripsi ...................................................... 35
Gambar 4.14 Pesan pemberitahuan dekripsi berhasil disimpan ................. 36
Gambar 4.15 Skema Jaringan Feistel Pada Algoritma Blowfish ................ 37
Gambar 4.16 Chart Waktu Enkripsi Tiap Mode ........................................ 40
Gambar 4.17 Chart Waktu Dekripsi Tiap Mode ....................................... 41
DAFTAR TABEL
Halaman
Tabel 2.1 Beberapa Contoh Blok Cipher .................................................. 11
Tabel 3.1 Spesifikasi Hardware ............................................................... 24
Tabel 3.2 Spesifikasi Software ................................................................. 25
Tabel 4.1 Tabel User ................................................................................ 28
Tabel 4.2 Pseudo Code Jaringan Feistel Algoritma Blowfish ................. 38
Tabel 4.3 Pseudo Code fungsi iterasi F() ................................................. 38
Tabel 4.4 Pseudo Code Pembangkitan Sub-kunci ................................... 39
Tabel 4.5 Data Masukan Uji Coba Aplikasi Proses Enkripsi .................. 40
Tabel 4.6 Data Masukan Uji Coba Aplikasi Proses Dekripsi .................. 41
Tabel 4.7 Kompleksitas Waktu Algoritma Blowfish ................................ 43
Tabel 4.8 Kompleksitas Waktu Tiap-tiap Mode ...................................... 43
DAFTAR LAMPIRAN
Halaman
Lampiran 1 8366 Digit HEX dari Pi (Key Expansion) ........................... 48
Lampiran 2 Form Login (LoginForm.java) ............................................. 51
Lampiran 3 Form Utama (FuguView.java) ............................................. 54
Lampiran 4 Form Enkripsi (BlowfishEnc.java) ....................................... 57
Lampiran 5 Form Dekripsi (BlowfishDec.java) ...................................... 69
Lampiran 6 Class Koneksi Database (DriverConnection.java) ............... 80
Lampiran 7 Class Algoritma Blowfish (BlowfishEngine.java) ............... 82
Lampiran 8 Class Mode Enkripsi CBC (CBCBlockCipher.java) ............ 95
Lampiran 9 Class Mode Enkripsi CFB (CFBBlockCipher.java) ............. 101
Lampiran 10 Class Mode Enkripsi OFB (OFBBlockCipher.java) ............ 107
BAB I
PENDAHULUAN
1
Prasetyo Bawono, S.Si
Universitas Sebelas Maret
library.uns.ac.id digilib.uns.ac.id
2
dekripsi, yaitu kebalikan dari proses enkripsi. Mengubah data yang terenkripsi
menjadi data semula. Dekripsi hanya bisa dilakukan oleh pihak yang berhak.
Enkripsi dan dekripsi merupakan bagian dari kinerja sebuah algoritma
kriptografi. Algoritma enkripsi yang akan digunakan dalam tugas akhir ini adalah
algoritma Blowfish.
BAB II
LANDASAN TEORI
Simbol Terminator
Simbol Proses
Simbol Keputusan
Simbol Alur
Simbol Dokumen
4
Prasetyo Bawono, S.Si
Universitas Sebelas Maret
library.uns.ac.id digilib.uns.ac.id
5
2.1.4 Kriptografi
Menurut Schneier (1996), kriptografi adalah ilmu dan seni untuk menjaga
keamanan pesan.
Menurut Menezes et al (1996), kriptografi adalah ilmu yang mempelajari
teknik-teknik matematika yang berhubungan dengan aspek keamanan informasi
seperti kerahasiaan, integritas data, serta otentikasi.
Menurut Munir (2006), kriptografi (cryptography) berasal dari Bahasa
Yunani: ”cryptos” artinya ”secret” (rahasia), sedangkan ”graphein” artinya
”writing” (tulisan), Jadi, kriptografi berarti ”secret writing” (tulisan rahasia).
Definisi yang digunakan di dalam buku-buku yang lama (sebelum tahun 1980-an)
menyatakan bahwa kriptografi adalah ilmu dan seni untuk menjaga kerahasiaan
pesan dengan cara menyandikannya ke dalam bentuk yang tidak dapat dimengerti
lagi maknanya. Definisi ini mungkin cocok pada masa lalu di mana kriptografi
digunakan untuk keamanan komunikasi penting seperti komunikasi di kalangan
militer, diplomat, dan mata-mata (spy). Namun saat ini kriptografi lebih dari
sekadar privacy, tetapi juga untuk tujuan data integrity, authentication, dan non-
repudation.
Menurut Munir (2006), di dalam kriptografi terdapat beberapa
terminologi/istilah penting yang perlu diketahui yaitu :
1. Pesan, Plainteks, dan Cipherteks
Pesan (message) adalah data atau informasi yang dapat dibaca atau dimengerti
maknanya. Nama lain untuk pesan adalah plainteks (plaintext) atau teks jelas
(cleartext). Pesan dapat berupa data atau informasi yang dikirim (melalui
kurir, saluran telekomunikasi, dsb) atau yang disimpan di dalam media
perekam (kertas, storage, dsb). Pesan yang tersimpan tidak hanya berupa teks,
tetapi juga dapat berbentuk citra (image), suara/bunyi (audio), dan video, atau
berkas biner lainnya.
Agar pesan tidak dapat dimengerti maknanya oleh pihak lain, maka pesan
perlu disandikan ke bentuk lain yang tidak dapat dipahami. Bentuk pesan yang
tersandi disebut cipherteks (ciphertext) atau kriptogram (cryptogram).
Cipherteks harus dapat ditransformasikan kembali menjadi plainteks semula
agar pesan yang diterima bisa dibaca.
2. Pengirim dan penerima
Komunikasi data melibatkan pertukaran pesan antara dua entitas. Pengirim
(sender) adalah entitas yang mengirim pesan kepada entitas lainnya. Penerima
(receiver) adalah entitas yang menerima pesan. Entitas disini dapat berupa
orang, mesin (komputer), kartu kredit, dan sebagainya. Pengirim tentu
menginginkan pesan yang dikirim tidak dapat dibaca/diketahui oleh pihak
lain, kecuali yang berhak menerimanya. Maka, pesan harus disandikan
menjadi cipherteks.
3. Enkripsi dan Dekripsi
Proses menyandikan plainteks menjadi cipherteks disebut enkripsi
(encryption) atau enciphering (standard nama menurut ISO 7498-2).
Sedangkan proses mengembalikan cipherteks menjadi plainteks semula
dinamakan dekripsi (decryption) atau deciphering (standard nama menurut
ISO 7498-2). Istilah encryption of data in motion mengacu pada enkripsi
pesan yang ditransmisikan melalui saluran komunikasi. Sedangkan istilah
encryption of data at-rest mengacu pada enkripsi dokumen yang disimpan di
dalam storage.
4. Cipher dan Kunci
Algoritma kriptografi disebut juga cipher, yaitu aturan untuk enciphering dan
deciphering, atau fungsi matematika yang digunakan untuk enkripsi dan
dekripsi. Kunci (key) adalah parameter yang digunakan untuk transformasi
enciphering dan deciphering. Kunci biasanya berupa string atau deretan
bilangan.
Kunci Kunci
Cipherteks
Plainteks Enkripsi Dekripsi Plainteks
Menurut Anjar Syafari (2007), Proses enkripsi dan deskripsi secara matematis
diterangkan sebagai berikut :
EK (M) = C (Proses Enkripsi)
DK (C) = M (Proses Deskripsi)
Keterangan :
EK : Enkripsi.
DK : Deskripsi.
M : Message (Pesan sebelum dienkripsi)
C : Cipher (Pesan setelah dienkrisi)
Tipe-tipe cipher :
Ciphers
6. Penyadap
Penyadap (eavesdropper) adalah orang yang mencoba menangkap pesan
selama ditransmisikan. Tujuan penyadap adalah untuk mendapatkan informasi
sebanyak-banyaknya mengenai sistem kriptogafi yang digunakan untuk
berkomunikasi dengan maksud untuk memecahkan cipherteks. Nama lain
penyadap: enemy, adversary, intruder, interceptor, bad guy.
7. Kriptoanalis dan Kriptologi
Kriptografi berkembang sedemikian rupa sehingga melahirkan bidang yang
berlawanan yaitu kriptanalisis. Kriptanalisis (cryptanalysis) adalah ilmu dan
seni untuk memecahkan cipherteks menjadi plainteks tanpa mengetahui kunci
yang digunakan. Pelakunya disebut kriptanalis. Kriptologi (cryptology) adalah
studi mengenai kriptografi dan kriptanalisis.
Kriptologi
Kriptografi Kriptanalis
Ilmu dan seni untuk menjaga Ilmu dan seni untuk memecahkan
keamanan pesan pesan yang terenkripsi (cipherteks)
Plainteks
Enkripsi
Kunci
Cipher Blok
Cipherteks
Cipherteks
Dekripsi
Kunci
Cipher Blok
Plainteks
(XL)i = (XR)i -1
Selain itu, sifat reversible tidak bergantung pada fungsi f sehingga fungsi f
dapat dibuat serumit mungkin. Skema jaringan Feistel dapat dilihat pada Gambar
2.7.
(XL)i - 1 Pi (XR)i - 1
(XL)i (XR)i
Algoritma Blowfish merupakan algoritma yang kuat, dan sampai saat ini
belum ditemukan kelemahan yang berarti. Algoritma Blowfish pun dapat
digabungkan dengan algoritma-algoritma enkripsi lainnya dalam mengenkripsi
sebuah informasi/pesan untuk lebih menjamin isi dari pesan tersebut.
Enkripsi data terdiri dari sebuah fungsi sederhana yang mengalami putaran
atau iterasi sebanyak 16 kali. Setiap putaran terdiri dari sebuah permutasi yang
bergantung pada kunci dan substitusi yang bergantung pada kunci dan data.
Seluruh operasi berupa penambahan dan XOR (⊕) dengan kata sepanjang 32 bit.
Operasi tambahan yang digunakan hanya berupa data look-up terhadap array
dengan empat indeks yang dilakukan setiap putaran.
Blowfish menggunakan sejumlah besar subkunci. Kunci-kunci tersebut
harus dibangkitkan terlebih dahulu sebelum proses enkripsi dan dekripsi data
dilakukan.
Menurut Sukmawan (2000), alur proses enkripsi algoritma Blowfish dapat
dijelaskan sebagai berikut:
1. P-array terdiri dari 18 buah subkunci dengan ukuran 32 bit:
P1, P2, ..., P18
2. Empat buah Kotak-S dengan ukuran 32 bit mempunyai masukan sebanyak
256 buah. Kotak-kotak tersebut adalah:
S1,0, S1,1, ..., S1,255
S2,0, S2,1, ..., S2,255
S3,0, S3,1, ..., S3,255
S4,0, S4,1, ..., S4,255
Subkunci dibangkitkan dengan menggunakan algoritma Blowfish.
3. Masukan terhadap jaringan Feistel ini adalah X, yang merupakan elemen data
(plainteks) dengan ukuran 64-bit. Bila kurang dari 64-bit, maka akan
dilakukan proses padding (penambahan bit).
4. Bagi X menjadi setengah bagian, yaitu dengan ukuran 32-bit. 32-bit pertama
disebut XL, 32-bit yang kedua disebut XR.
XL = XL ⊕ Pi
XR = F(XL) ⊕ XR
Kemudian tukar XL dengan XR.
Keterangan:
i = 1, 2, …, 16 (menunjukkan nomor putaran/iterasi)
6. Setelah melakukan perulangan yang ke-16, lakukan lagi proses penukaran XL
dengan XR.
Ci = EK (Mi)
dan proses dekripsi sebagai berikut:
Mi = DK (Ci)
Dalam hal ini, Mi dan Ci merupakan blok plainteks dan cipherteks ke-i.
Skema enkripsi dan dekripsi dengan mode ECB dapat dilihat pada Gambar
2.9
ENKRIPSI DEKRIPSI
Blok Plainteks M1 Blok Cipherteks C1
m1 m2 m.. mn c1 c2 c... cn
M = (m1, m2, …, mn) C = (c1, c2, …, cn)
Kunci K E Kunci K E
Ci = EK (Mi⊕Ci-1)
sedangkan proses dekripsi dapat dinyatakan sebagai berikut:
Mi = DK (Ci)⊕Ci-1
yang dalam hal ini, C0 = IV (Initialization Vector). IV dapat diberikan oleh
pengguna atau dibangkitkan secara acak oleh aplikasi. IV ini merupakan
rangkaian bit yang tidak bermakna dan hanya digunakan sebagai inisialisasi
untuk membuat setiap blok cipherteks menjadi unik. Jadi, untuk
menghasilkan blok cipherteks pertama (C1), IV digunakan untuk
menggantikan blok cipherteks sebelumnya, C0. Sebaliknya pada proses
dekripsi, blok plainteks diperoleh dengan cara meng-XOR-kan IV dengan
hasil dekripsi terhadap blok cipherteks pertama.
Dengan mode operasi CBC, kesalahan pada satu bit plainteks akan
mempengaruhi blok cipherteks yang berkoresponden dan blok-blok
cipherteks selanjutnya. Sedangkan kesalahan satu bit pada cipherteks hanya
akan mempengaruhi satu blok plainteks yang berkoresponden dan satu bit
pada blok berikutnya dengan posisi bit yang berkoresponden pula.
ENKRIPSI DEKRIPSI
Mi-1 Mi-1 Ci-1 Ci
Ci-2 ⊕ ⊕
Kunci K EK EK Kunci K DK DK
Ci-2 ⊕ ⊕
Ci-1 Ci Mi-1 Mi
Ci = Mi ⊕ MSBb (EK(Xi))
Mi = Ci ⊕ MSBb (DK(Xi))
K EK K DK
mi ⊕ ci ci ⊕ mi
Gambar 2.11. Skema Enkripsi dan Dekripsi dengan Mode CFB 8-Bit
Pada mode CFB pun terdapat perambatan kesalahan baik pada proses
enkripsi maupun proses dekripsi. Pada proses enkripsi, kesalahan satu bit
pada plainteks mempengaruhi blok cipherteks yang berkoresponden dan blok-
blok cipherteks berikutnya. Sedangkan kesalahan satu bit pada blok
cipherteks akan bit yang berkoresponden dan bit-bit lainnya selama bit error
tersebut terdapat di dalam pergeseran bit (shift register). Pada mode CFB 8-
bit dan ukuran blok 64 bit, maka kesalahan satu byte pada blok cipherteks
akan mempengaruhi satu byte plainteks yang berkoresponden dan delapan
byte berikutnya (lama byte error yang terdapat dalam shift register adalah
delapan putaran).
4. Output FeedBack (OFB)
Mode OFB bekerja dengan cara yang mirip dengan mode CFB,
kecuali n-bit dari hasil fungsi enkripsi terhadap antrian disalin menjadi
elemen paling kanan antrian. Secara formal, mode OFB n-bit dapat
dinyatakan sebagai berikut:
Ci = Mi ⊕ MSBb (EK(Xi))
Mi = Ci ⊕ MSBb (DK(Xi))
ENKRIPSI DEKRIPSI
Antrian 8-byte Antrian 8-byte
K EK K DK
mi ⊕ ci ci ⊕ mi
Gambar 2.12 Skema Enkripsi dan Dekripsi pada mode OFB 8-Bit
`BAB III
METODE PENELITIAN
24
b. Software
Tabel 3.2 Spesifikasi Software
Jenis Spesifikasi
Sistem Operasi - Microsoft(R) Windows(R) eXPerience (XP)
Professional SP3
- Ubuntu 9.10 Karmic Koala
Bahasa Java 2 Standard Edition
Pemrograman - Java Development Kit (JDK) 1.6.0_11
- Java Runtime Environment (JRE) 6
IDE Netbeans 6.5
Database Server MySQL Server 5.1
Database Manager Navicat Lite 8 for MySQL
BAB IV
PEMBAHASAN
File
Cipherteks
Plainteks Teks ter-Enkripsi Teks ter-Dekripsi Plainteks
26
Begin
Login
Tidak
Sukses ?
Ya
Enkripsi /
Enkripsi Dekripsi
Dekripsi ?
Ya Ya
Plainteks Cipherteks
Kunci Kunci
Ya Ya
Kunci = 0 / Kunci = 0 /
Kunci < 8 ? Kunci < 8 ?
Tidak
Tidak Tidak
Cipherteks Plainteks
Logout? Logout?
Tidak Tidak
Quit? Quit?
Ya End Ya
username
password
login
plainteks
cipherteks
cipherteks
plainteks
Perlu diperhatikan bahwa pada saat enkripsi dan dekripsi data, mode
enkripsi cipher blok yang dipilih harus sama dengan mode dekripsi cipher blok.
Jika tidak, maka akan terjadi kesalahan dalam proses dekripsinya.
Plainteks / X (64-bit)
XL (32-bit) XR (32-bit)
P1
P2
13 Putaran
P16
P18 P17
Cipherteks (64-bit)
1400
1200
1000
800
Time (ms) Perf 1
600 Perf 2
Perf 3
400
200
0
ECB CBC CFB OFB
Mode Enkripsi
1200
1000
800
Time (ms)
600 Perf 1
Perf 2
400 Perf 3
200
0
ECB CBC CFB OFB
Mode Dekripsi
1 Begin
2 Algorithm:
3 (xL, xR) = X // Bagi X menjadi 2 bagian, 32-bit/bagian O(1)
4 Loop on i from = 1 to 16 // Lakukan iterasi 0(n)
5 xL = xL XOR Pi // Operasi XOR xL dgn Pi
6 xR = F(xL) XOR xR // Operasi XOR F(xL) dgn xR
7 Swap xL and xR // Tukar xL dgn xR
8 End of loop // Akhir looping
9 Swap xL and xR // Tukar lagi xL dgn xR 0(1)
10 xR = xR XOR P17 // Operasi XOR xR dgn P17 -> xR 0(1)
11 xL = xL XOR P18 // Operasi XOR xL dgn P18 -> xL 0(1)
12 C = (xL, xR) // 64 bit cipherteks O(1)
13 End
BAB V
PENUTUP
5.1 Kesimpulan
Berdasarkan pembahasan dapat diambil kesimpulan sebagai berikut:
1. Telah dibuat sistem pengamanan data dengan menggunakan algoritma
Blowfish, khususnya data teks.
2. Aplikasi yang dibuat memiliki pilihan mode enkripsi cipher blok.
3. Blowfish merupakan salah satu solusi yang baik untuk mengatasi masalah
keamanan dan kerahasiaan data yang pada umumnya diterapkan dalam
saluran komunikasi dan berkas.
4. Algoritma Blowfish merupakan algoritma dengan operasi yang sederhana
dan menggunakan jaringan Feistel
5. Tingkat keamanan algoritma Blowfish ditentukan oleh jumlah iterasi dan
panjang kunci yang digunakan.
6. Algoritma Blowfish merupakan algoritma yang kuat, yang belum
ditemukan titik lemahnya.
7. Tidak ada perbedaan waktu enkripsi yang signifikan antara mode-mode
enkripsi yang ada, dengan hasil-hasil sebagai berikut:
a) Waktu enkripsi dengan mode ECB (Electronic Code Book) untuk
data 22 byte sebesar 703 ms (millisecond), data 206.080 byte
sebesar 955 ms, data 1.052.632 byte sebesar 1.297 ms.
b) Waktu enkripsi dengan mode CBC (Cipher Block Chainning)
untuk data 22 byte sebesar 700 ms (millisecond), data 206.080
byte sebesar 969 ms, data 1.052.632 byte sebesar 1.328 ms.
c) Waktu enkripsi dengan mode CFB (Cipher Feed Back) untuk data
22 byte sebesar 738 ms (millisecond), data 206.080 byte sebesar
968 ms, data 1.052.632 byte sebesar 1.344 ms.
d) Waktu enkripsi dengan mode OFB (Output Feed Back) untuk data
22 byte sebesar 693 ms (millisecond), data 206.080 byte sebesar
969 ms, data 1.052.632 byte sebesar 1.312 ms.
5.2 Saran
Pada penulisan skripsi ini dibuat sistem pengamanan data dengan
menggunakan algoritma Blowfish dengan teks sebagai data masukannya. Untuk
selanjutnya dapat dikembangkan lagi sistem yang mampu menerima input berkas
tidak hanya teks, namun juga bisa berkas suara, video maupun yang lainnya.
DAFTAR PUSTAKA
LAMPIRAN
243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89
452821E638D01377BE5466CF34E90C6CC0AC29B7C97C50DD3F84D5B5B5470917
9216D5D98979FB1BD1310BA698DFB5AC2FFD72DBD01ADFB7B8E1AFED6A267E96
BA7C9045F12C7F9924A19947B3916CF70801F2E2858EFC16636920D871574E69
A458FEA3F4933D7E0D95748F728EB658718BCD5882154AEE7B54A41DC25A59B5
9C30D5392AF26013C5D1B023286085F0CA417918B8DB38EF8E79DCB0603A180E
6C9E0E8BB01E8A3ED71577C1BD314B2778AF2FDA55605C60E65525F3AA55AB94
5748986263E8144055CA396A2AAB10B6B4CC5C341141E8CEA15486AF7C72E993
B3EE1411636FBC2A2BA9C55D741831F6CE5C3E169B87931EAFD6BA336C24CF5C
7A325381289586773B8F48986B4BB9AFC4BFE81B6628219361D809CCFB21A991
487CAC605DEC8032EF845D5DE98575B1DC262302EB651B8823893E81D396ACC5
0F6D6FF383F442392E0B4482A484200469C8F04A9E1F9B5E21C66842F6E96C9A
670C9C61ABD388F06A51A0D2D8542F68960FA728AB5133A36EEF0B6C137A3BE4
BA3BF0507EFB2A98A1F1651D39AF017666CA593E82430E888CEE8619456F9FB4
7D84A5C33B8B5EBEE06F75D885C12073401A449F56C16AA64ED3AA62363F7706
1BFEDF72429B023D37D0D724D00A1248DB0FEAD349F1C09B075372C980991B7B
25D479D8F6E8DEF7E3FE501AB6794C3B976CE0BD04C006BAC1A94FB6409F60C4
5E5C9EC2196A246368FB6FAF3E6C53B51339B2EB3B52EC6F6DFC511F9B30952C
CC814544AF5EBD09BEE3D004DE334AFD660F2807192E4BB3C0CBA85745C8740F
D20B5F39B9D3FBDB5579C0BD1A60320AD6A100C6402C7279679F25FEFB1FA3CC
8EA5E9F8DB3222F83C7516DFFD616B152F501EC8AD0552AB323DB5FAFD238760
53317B483E00DF829E5C57BBCA6F8CA01A87562EDF1769DBD542A8F6287EFFC3
AC6732C68C4F5573695B27B0BBCA58C8E1FFA35DB8F011A010FA3D98FD2183B8
4AFCB56C2DD1D35B9A53E479B6F84565D28E49BC4BFB9790E1DDF2DAA4CB7E33
62FB1341CEE4C6E8EF20CADA36774C01D07E9EFE2BF11FB495DBDA4DAE909198
EAAD8E716B93D5A0D08ED1D0AFC725E08E3C5B2F8E7594B78FF6E2FBF2122B64
8888B812900DF01C4FAD5EA0688FC31CD1CFF191B3A8C1AD2F2F2218BE0E1777
EA752DFE8B021FA1E5A0CC0FB56F74E818ACF3D6CE89E299B4A84FE0FD13E0B7
7CC43B81D2ADA8D9165FA2668095770593CC7314211A1477E6AD206577B5FA86
C75442F5FB9D35CFEBCDAF0C7B3E89A0D6411BD3AE1E7E4900250E2D2071B35E
226800BB57B8E0AF2464369BF009B91E5563911D59DFA6AA78C14389D95A537F
207D5BA202E5B9C5832603766295CFA911C819684E734A41B3472DCA7B14A94A
1B5100529A532915D60F573FBC9BC6E42B60A47681E6740008BA6FB5571BE91F
F296EC6B2A0DD915B6636521E7B9F9B6FF34052EC585566453B02D5DA99F8FA1
08BA47996E85076A4B7A70E9B5B32944DB75092EC4192623AD6EA6B049A7DF7D
9CEE60B88FEDB266ECAA8C71699A17FF5664526CC2B19EE1193602A575094C29
A0591340E4183A3E3F54989A5B429D656B8FE4D699F73FD6A1D29C07EFE830F5
4D2D38E6F0255DC14CDD20868470EB266382E9C6021ECC5E09686B3F3EBAEFC9
3C9718146B6A70A1687F358452A0E286B79C5305AA5007373E07841C7FDEAE5C
8E7D44EC5716F2B8B03ADA37F0500C0DF01C1F040200B3FFAE0CF51A3CB574B2
25837A58DC0921BDD19113F97CA92FF69432477322F547013AE5E58137C2DADC
C8B576349AF3DDA7A94461460FD0030EECC8C73EA4751E41E238CD993BEA0E2F
3280BBA1183EB3314E548B384F6DB9086F420D03F60A04BF2CB8129024977C79
5679B072BCAF89AFDE9A771FD9930810B38BAE12DCCF3F2E5512721F2E6B7124
501ADDE69F84CD877A5847187408DA17BC9F9ABCE94B7D8CEC7AEC3ADB851DFA
63094366C464C3D2EF1C18473215D908DD433B3724C2BA1612A14D432A65C451
50940002133AE4DD71DFF89E10314E5581AC77D65F11199B043556F1D7A3C76B
3C11183B5924A509F28FE6ED97F1FBFA9EBABF2C1E153C6E86E34570EAE96FB1
860E5E0A5A3E2AB3771FE71C4E3D06FA2965DCB999E71D0F803E89D65266C825
2E4CC9789C10B36AC6150EBA94E2EA78A5FC3C531E0A2DF4F2F74EA7361D2B3D
1939260F19C279605223A708F71312B6EBADFE6EEAC31F66E3BC4595A67BC883
B17F37D1018CFF28C332DDEFBE6C5AA56558218568AB9802EECEA50FDB2F953B
2AEF7DAD5B6E2F841521B62829076170ECDD4775619F151013CCA830EB61BD96
0334FE1EAA0363CFB5735C904C70A239D59E9E0BCBAADE14EECC86BC60622CA7
9CAB5CABB2F3846E648B1EAF19BDF0CAA02369B9655ABB5040685A323C2AB4B3
319EE9D5C021B8F79B540B19875FA09995F7997E623D7DA8F837889A97E32D77
11ED935F166812810E358829C7E61FD696DEDFA17858BA9957F584A51B227263
9B83C3FF1AC24696CDB30AEB532E30548FD948E46DBC312858EBF2EF34C6FFEA
FE28ED61EE7C3C735D4A14D9E864B7E342105D14203E13E045EEE2B6A3AAABEA
DB6C4F15FACB4FD0C742F442EF6ABBB5654F3B1D41CD2105D81E799E86854DC7
E44B476A3D816250CF62A1F25B8D2646FC8883A0C1C7B6A37F1524C369CB7492
47848A0B5692B285095BBF00AD19489D1462B17423820E0058428D2A0C55F5EA
1DADF43E233F70613372F0928D937E41D65FECF16C223BDB7CDE3759CBEE7460
4085F2A7CE77326EA607808419F8509EE8EFD85561D99735A969A7AAC50C06C2
5A04ABFC800BCADC9E447A2EC3453484FDD567050E1E9EC9DB73DBD3105588CD
675FDA79E3674340C5C43465713E38D83D28F89EF16DFF20153E21E78FB03D4A
E6E39F2BDB83ADF7E93D5A68948140F7F64C261C94692934411520F77602D4F7
BCF46B2ED4A20068D40824713320F46A43B7D4B7500061AF1E39F62E97244546
14214F74BF8B88404D95FC1D96B591AF70F4DDD366A02F45BFBC09EC03BD9785
7FAC6DD031CB850496EB27B355FD3941DA2547E6ABCA0A9A28507825530429F4
0A2C86DAE9B66DFB68DC1462D7486900680EC0A427A18DEE4F3FFEA2E887AD8C
B58CE0067AF4D6B6AACE1E7CD3375FECCE78A399406B2A4220FE9E35D9F385B9
EE39D7AB3B124E8B1DC9FAF74B6D185626A36631EAE397B23A6EFA74DD5B4332
6841E7F7CA7820FBFB0AF54ED8FEB397454056ACBA48952755533A3A20838D87
FE6BA9B7D096954B55A867BCA1159A58CCA9296399E1DB33A62A4A563F3125F9
5EF47E1C9029317CFDF8E80204272F7080BB155C05282CE395C11548E4C66D22
48C1133FC70F86DC07F9C9EE41041F0F404779A45D886E17325F51EBD59BC0D1
F2BCC18F41113564257B7834602A9C60DFF8E8A31F636C1B0E12B4C202E1329E
AF664FD1CAD181156B2395E0333E92E13B240B62EEBEB92285B2A20EE6BA0D99
DE720C8C2DA2F728D012784595B794FD647D0862E7CCF5F05449A36F877D48FA
C39DFD27F33E8D1E0A476341992EFF743A6F6EABF4F8FD37A812DC60A1EBDDF8
991BE14CDB6E6B0DC67B55106D672C372765D43BDCD0E804F1290DC7CC00FFA3
B5390F92690FED0B667B9FFBCEDB7D9CA091CF0BD9155EA3BB132F88515BAD24
7B9479BF763BD6EB37392EB3CC1159798026E297F42E312D6842ADA7C66A2B3B
12754CCC782EF11C6A124237B79251E706A1BBE64BFB63501A6B101811CAEDFA
3D25BDD8E2E1C3C9444216590A121386D90CEC6ED5ABEA2A64AF674EDA86A85F
BEBFE98864E4C3FE9DBC8057F0F7C08660787BF86003604DD1FD8346F6381FB0
7745AE04D736FCCC83426B33F01EAB71B08041873C005E5F77A057BEBDE8AE24
55464299BF582E614E58F48FF2DDFDA2F474EF388789BDC25366F9C3C8B38E74
B475F25546FCD9B97AEB26618B1DDF84846A0E79915F95E2466E598E20B45770
8CD55591C902DE4CB90BACE1BB8205D011A862487574A99EB77F19B6E0A9DC09
662D09A1C4324633E85A1F0209F0BE8C4A99A0251D6EFE101AB93D1D0BA5A4DF
A186F20F2868F169DCB7DA83573906FEA1E2CE9B4FCD7F5250115E01A70683FA
A002B5C40DE6D0279AF88C27773F8641C3604C0661A806B5F0177A28C0F586E0
006058AA30DC7D6211E69ED72338EA6353C2DD94C2C21634BBCBEE5690BCB6DE
EBFC7DA1CE591D766F05E4094B7C018839720A3D7C927C2486E3725F724D9DB9
1AC15BB4D39EB8FCED54557808FCA5B5D83D7CD34DAD0FC41E50EF5EB161E6F8
A28514D96C51133C6FD5C7E756E14EC4362ABFCEDDC6C837D79A323492638212
670EFA8E406000E03A39CE37D3FAF5CFABC277375AC52D1B5CB0679E4FA33742
D382274099BC9BBED5118E9DBF0F7315D62D1C7EC700C47BB78C1B6B21A19045
B26EB1BE6A366EB45748AB2FBC946E79C6A376D26549C2C8530FF8EE468DDE7D
D5730A1D4CD04DC62939BBDBA9BA4650AC9526E8BE5EE304A1FAD5F06A2D519A
63EF8CE29A86EE22C089C2B843242EF6A51E03AA9CF2D0A483C061BA9BE96A4D
8FE51550BA645BD62826A2F9A73A3AE14BA99586EF5562E9C72FEFD3F752F7DA
3F046F6977FA0A5980E4A91587B086019B09E6AD3B3EE593E990FD5A9E34D797
2CF0B7D9022B8B5196D5AC3A017DA67DD1CF3ED67C7D2D281F9F25CFADF2B89B
5AD6B4725A88F54CE029AC71E019A5E647B0ACFDED93FA9BE8D3C48D283B57CC
F8D5662979132E28785F0191ED756055F7960E44E3D35E8C15056DD488F46DBA
03A161250564F0BDC3EB9E153C9057A297271AECA93A072A1B3F6D9B1E6321F5
F59C66FB26DCF3197533D928B155FDF5035634828ABA3CBB28517711C20AD9F8
ABCC5167CCAD925F4DE817513830DC8E379D58629320F991EA7A90C2FB3E7BCE
5121CE64774FBE32A8B6E37EC3293D4648DE53696413E680A2AE0810DD6DB224
69852DFD09072166B39A460A6445C0DD586CDECF1C20C8AE5BBEF7DD1B588D40
CCD2017F6BB4E3BBDDA26A7E3A59FF453E350A44BCB4CDD572EACEA8FA6484BB
8D6612AEBF3C6F47D29BE463542F5D9EAEC2771BF64E6370740E0D8DE75B1357
F8721671AF537D5D4040CB084EB4E2CC34D2466A0115AF84E1B0042895983A1D
06B89FB4CE6EA0486F3F3B823520AB82011A1D4B277227F8611560B1E7933FDC
BB3A792B344525BDA08839E151CE794B2F32C9B7A01FBAC9E01CC87EBCC7D1F6
CF0111C3A1E8AAC71A908749D44FBD9AD0DADECBD50ADA380339C32AC6913667
8DF9317CE0B12B4FF79E59B743F5BB3AF2D519FF27D9459CBF97222C15E6FC2A
0F91FC719B941525FAE59361CEB69CEBC2A8645912BAA8D1B6C1075EE3056A0C
10D25065CB03A442E0EC6E0E1698DB3B4C98A0BE3278E9649F1F9532E0D392DF
D3A0342B8971F21E1B0A74414BA3348CC5BE7120C37632D8DF359F8D9B992F2E
E60B6F470FE3F11DE54CDA541EDAD891CE6279CFCD3E7E6F1618B166FD2C1D05
848FD2C5F6FB2299F523F357A632762393A8353156CCCD02ACF081625A75EBB5
6E16369788D273CCDE96629281B949D04C50901B71C65614E6C6C7BD327A140A
45E1D006C3F27B9AC9AA53FD62A80F00BB25BFE235BDD2F671126905B2040222
B6CBCF7CCD769C2B53113EC01640E3D338ABBD602547ADF0BA38209CF746CE76
77AFA1C52075606085CBFE4E8AE88DD87AAAF9B04CF9AA7E1948C25C02FB8A8C
01C36AE4D6EBE1F990D4F869A65CDEA03F09252DC208E69FB74E6132CE77E25B
578FDFE33AC372E6
package fugu;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.sql.SQLException;
import javax.swing.JOptionPane;
import fugu.dbase.*;
/**
*
* @author prasetyo bawono
*/
public class LoginForm extends javax.swing.JDialog {
Dimension screenSize =
Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = this.getSize();
if (frameSize.height > screenSize.height){
frameSize.height = screenSize.height;
}
if (frameSize.width > screenSize.width) {
frameSize.width = screenSize.width;
}
this.setLocation((screenSize.width - frameSize.width) / 2,
(screenSize.height - frameSize.height) / 2);
this.setTitle("Login Form");
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
LoginForm dialog = new LoginForm(new
javax.swing.JFrame(), true);
dialog.addWindowListener(new
java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent
e) {
System.exit(0);
}
});
dialog.setVisible(true);
}
});
}
q1.setStrSql(strSql);
q1.makeActive(true);
if(q1.getRowCount()>0){
FuguApp.getInstanceMainMenu().setAuthentication(true);
FuguApp.getApplication().ShowMainMenu();
this.dispose();
}
else {
JOptionPane.showMessageDialog(LoginForm.this, "Username dan
Password Salah Bro !", "ERROR", JOptionPane.ERROR_MESSAGE);
}
/*
* FuguView.java
* Menu Utama
* @ Prasetyo Bawono
* @ jendalsepit@gmail.com
* nb: Semua konstruktor swing tidak disertakan.
* Full Source: http://ono.web.id/fugu
*/
package fugu;
import fugu.mode.BlowfishDec;
import fugu.mode.BlowfishEnc;
import org.jdesktop.application.Action;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import javax.swing.JDialog;
import javax.swing.JFrame;
/**
* The application's main frame.
*/
public class FuguView extends FrameView {
initComponents();
}
@Action
public void showAboutBox() {
if (aboutBox == null) {
JFrame mainFrame = FuguApp.getApplication().getMainFrame();
aboutBox = new FuguAboutBox(mainFrame);
aboutBox.setLocationRelativeTo(mainFrame);
}
FuguApp.getApplication().show(aboutBox);
}
private void
menuNotepadDecryptActionPerformed(java.awt.event.ActionEvent evt) {//GEN-
FIRST:event_menuNotepadDecryptActionPerformed
// TODO add your handling code here:
setEnc(true);
new BlowfishDec(new javax.swing.JFrame(),true).setVisible(true);
}//GEN-LAST:event_menuNotepadDecryptActionPerformed
private void
menuNotepadEncryptActionPerformed(java.awt.event.ActionEvent evt) {//GEN-
FIRST:event_menuNotepadEncryptActionPerformed
// TODO add your handling code here:
setEnc(true);
new BlowfishEnc(new javax.swing.JFrame(),true).setVisible(true);
}//GEN-LAST:event_menuNotepadEncryptActionPerformed
if(value==true){
// mn_enc.setEnabled(false);
// mn_dec.setEnabled(false);
}
else{
fileMenu.setEnabled(true);
helpMenu.setEnabled(true);
}
}
}
package fugu.mode;
import fugu.FuguApp;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.jdesktop.application.Application;
import org.jdesktop.application.ResourceMap;
/**
*
* @author prasetyo bawono
*/
public class BlowfishEnc extends javax.swing.JDialog {
Dimension screenSize =
Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = this.getSize();
this.setLocation((screenSize.width - frameSize.width) / 2,
(screenSize.height - frameSize.height) / 2);
this.setTitle("Encryption Mode");
// Define Clickable
textAreaPlain.setEnabled(false);
ResourceMap resourceMap =
Application.getInstance(fugu.FuguApp.class).getContext().getResourceMap(B
lowfishEnc.class);
textAreaPlain.setBackground(resourceMap.getColor("textAreaCipher.backgrou
nd"));
btnNewPlainText.setEnabled(true);
btnSavePlainText.setEnabled(false);
btnOpenPlainText.setEnabled(false);
btnEncryptPlainText.setEnabled(false);
btnSaveCipherText.setEnabled(false);
btnResetPrivKey.setEnabled(false);
txtPassword.setEnabled(false);
btnNewPlainText.requestFocus();
private void
btnNewPlainTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-
FIRST:event_btnNewPlainTextActionPerformed
// TODO add your handling code here:
if (evt.getSource() == this.btnNewPlainText){
// Define Clickable
textAreaPlain.setEnabled(true);
textAreaPlain.setBackground(Color.WHITE);
btnNewPlainText.setEnabled(false);
btnSavePlainText.setEnabled(true);
btnOpenPlainText.setEnabled(true);
btnEncryptPlainText.setEnabled(true);
btnResetPrivKey.setEnabled(true);
txtPassword.setEnabled(true);
// setAuthPlainText(true);
this.textAreaPlain.setText("");
this.textAreaCipher.setText("");
this.txtPassword.setText("");
this.tfBenchmark.setText("");
this.tfCipherSize.setText("");
}
}//GEN-LAST:event_btnNewPlainTextActionPerformed
private void
btnSavePlainTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-
FIRST:event_btnSavePlainTextActionPerformed
if (evt.getSource() == this.btnSavePlainText){
JFileChooser savePlainText = new JFileChooser();
FileNameExtensionFilter filter = new
FileNameExtensionFilter("Text Documents (*.txt)", "txt", "java");
savePlainText.setFileFilter(filter);
savePlainText.setDialogTitle("Save PlainText to File");
int option = savePlainText.showSaveDialog(this);
// Jika OK
if (option == JFileChooser.APPROVE_OPTION){
try {
// Buat buffered writer untuk menulis
BufferedWriter out = new BufferedWriter(new
FileWriter(savePlainText.getSelectedFile().getPath()));
// BufferedWriter out = new BufferedWriter(new
OutputStreamWriter(new
FileOutputStream(savePlainText.getSelectedFile().getPath()),"UTF-8"));
out.write(this.textAreaPlain.getText());
out.close();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
JOptionPane.showMessageDialog(null, "Sukses Menyimpan
File "+savePlainText.getSelectedFile().getName()+"\nLokasi File:
"+savePlainText.getSelectedFile(),"PlainText Saved!",
JOptionPane.INFORMATION_MESSAGE);
} else
JOptionPane.showMessageDialog(null, "Something
Happened?", "Gagal Menyimpan File", JOptionPane.ERROR_MESSAGE);
}
}//GEN-LAST:event_btnSavePlainTextActionPerformed
private void
menuNotepadQuitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-
FIRST:event_menuNotepadQuitActionPerformed
// TODO add your handling code here:
FuguApp.getApplication().ShowMainMenu();
FuguApp.getInstanceMainMenu().setAuthentication(true);
this.dispose();
}//GEN-LAST:event_menuNotepadQuitActionPerformed
private void
btnOpenPlainTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-
FIRST:event_btnOpenPlainTextActionPerformed
JFileChooser openPlainText = new JFileChooser();
openPlainText.setFileSelectionMode(JFileChooser.FILES_ONLY);
openPlainText.setDialogTitle("Open Plain Text File(s)");
private void
btnResetPrivKeyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-
FIRST:event_btnResetPrivKeyActionPerformed
// TODO add your handling code here:
if (evt.getSource() == this.btnResetPrivKey)
this.txtPassword.setText("");
}//GEN-LAST:event_btnResetPrivKeyActionPerformed
private void
btnEncryptPlainTextActionPerformed(java.awt.event.ActionEvent evt)
{//GEN-FIRST:event_btnEncryptPlainTextActionPerformed
// Encrypt:
// ========
// Plain(String) -> Plain(String->Byte Array[]) -> Cipher(Byte
Array[]->String) -> Cipher(String)
if(txtPassword.getPassword().length<8 &&
txtPassword.getPassword().length>0){
try {
JOptionPane.showMessageDialog(null, "Private
key minimal 8 karakter", "Error", JOptionPane.ERROR_MESSAGE);
btnResetPrivKey.setEnabled(true);
txtPassword.setEnabled(true);
txtPassword.requestFocus();
} catch (Exception e) {
System.err.print(e);
}
if (txtPassword.getPassword().length>=8) {
Security.addProvider(new
org.bouncycastle.jce.provider.BouncyCastleProvider());
String textPlainStr = textAreaPlain.getText();
char[] textPassword = txtPassword.getPassword();
// ECB MODE
if (rbECB.isSelected()) {
try {
long ecbStart;
long ecbEnd;
long ecbTime;
ecbStart = System.currentTimeMillis();
SecretKeySpec key = new
SecretKeySpec(textPasswordByte, "Blowfish");
Cipher cipher =
Cipher.getInstance("Blowfish/ECB/PKCS5Padding","BC");
// Encryption
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherText =
cipher.doFinal(textPlainStrByte);
int ctLength =
cipher.update(textPlainStrByte, 0, textPlainStrByte.length, cipherText,
0);
ctLength += cipher.doFinal(cipherText,
ctLength);
textAreaCipher.setText(new
String(cipherText));
String ctLengthStr =
Integer.toString(ctLength);
tfCipherSize.setText(ctLengthStr);
} catch (Exception e) {
System.err.println(e);
}
}
// CBC MODE
if (rbCBC.isSelected()){
try {
long cbcStart;
long cbcEnd;
long cbcTime;
// Inisialization Vector
byte[] ivBytes = new byte[]{
0x07, 0x06, 0x05, 0x04,
0x03, 0x02, 0x01, 0x00
};
// Encryption
cipher.init(Cipher.ENCRYPT_MODE, key,
ivSpec);
byte[] cipherText =
cipher.doFinal(textPlainStrByte);
int ctLength =
cipher.update(textPlainStrByte, 0, textPlainStrByte.length, cipherText,
0);
ctLength += cipher.doFinal(cipherText,
ctLength);
textAreaCipher.setText(new
String(cipherText));
String ctLengthStr =
Integer.toString(ctLength);
tfCipherSize.setText(ctLengthStr);
// OFB MODE
if (rbOFB.isSelected()){
try {
long ofbStart;
long ofbEnd;
long ofbTime;
// Initialization Vector IV
byte[] ivBytes = new byte[]{
0x07, 0x06, 0x05, 0x04,
0x03, 0x02, 0x01, 0x00
};
// Define Algorithm
ofbStart = System.currentTimeMillis();
SecretKeySpec key = new
SecretKeySpec(textPasswordByte, "Blowfish");
IvParameterSpec ivSpec = new
IvParameterSpec(ivBytes);
Cipher cipher =
Cipher.getInstance("Blowfish/OFB/NoPadding", "BC");
// Encryption
cipher.init(Cipher.ENCRYPT_MODE, key,
ivSpec);
byte[] cipherText =
cipher.doFinal(textPlainStrByte);
int ctLength =
cipher.update(textPlainStrByte, 0, textPlainStrByte.length, cipherText,
0);
ctLength += cipher.doFinal(cipherText,
ctLength);
textAreaCipher.setText(new
String(cipherText));
String ctLengthStr =
Integer.toString(ctLength);
tfCipherSize.setText(ctLengthStr);
} catch (Exception e) {
System.err.println(e);
}
}
// CFB MODE
if (rbCFB.isSelected()){
try {
long cfbStart;
long cfbEnd;
long cfbTime;
// Initialization Vector IV
byte[] ivBytes = new byte[]{
0x07, 0x06, 0x05, 0x04,
0x03, 0x02, 0x01, 0x00
};
// Define Algorithm
cfbStart = System.currentTimeMillis();
SecretKeySpec key = new
SecretKeySpec(textPasswordByte, "Blowfish");
IvParameterSpec ivSpec = new
IvParameterSpec(ivBytes);
Cipher cipher =
Cipher.getInstance("Blowfish/CFB/NoPadding", "BC");
// Encryption
cipher.init(Cipher.ENCRYPT_MODE, key,
ivSpec);
byte[] cipherText =
cipher.doFinal(textPlainStrByte);
int ctLength =
cipher.update(textPlainStrByte, 0, textPlainStrByte.length, cipherText,
0);
ctLength += cipher.doFinal(cipherText,
ctLength);
textAreaCipher.setText(new
String(cipherText));
String ctLengthStr =
Integer.toString(ctLength);
tfCipherSize.setText(ctLengthStr);
String b = String.valueOf(cfbTime); //
9223372036854775807 9223372036854775807
tfBenchmark.setText(b);
} catch (Exception e) {
System.err.println(e);
}
}
JOptionPane.showMessageDialog(null, "Enkripsi
Berhasil..", "Encryption Successfully", JOptionPane.INFORMATION_MESSAGE);
btnResetPrivKey.setEnabled(false);
txtPassword.setEnabled(false);
}
}
else {
JOptionPane.showMessageDialog(null, "Plainteks tidak
boleh kosong", "Error Message", JOptionPane.ERROR_MESSAGE);
}
}
btnNewPlainText.setEnabled(true);
btnSavePlainText.setEnabled(false);
btnOpenPlainText.setEnabled(false);
btnEncryptPlainText.setEnabled(false);
btnSaveCipherText.setEnabled(true);
btnSaveCipherText.requestFocus();
}//GEN-LAST:event_btnEncryptPlainTextActionPerformed
private void
btnSaveCipherTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-
FIRST:event_btnSaveCipherTextActionPerformed
if (evt.getSource() == this.btnSaveCipherText){
JFileChooser saveCipherText = new JFileChooser();
FileNameExtensionFilter filter = new
FileNameExtensionFilter("CipherText File (*.cip)", "cip");
saveCipherText.setFileFilter(filter);
saveCipherText.setDialogTitle("Save CipherText to File");
int option = saveCipherText.showSaveDialog(this);
// Jika OK
if (option == JFileChooser.APPROVE_OPTION){
try {
// Buat buffered writer untuk menulis
BufferedWriter outs = new BufferedWriter(new
FileWriter(saveCipherText.getSelectedFile().getPath()));
// BufferedWriter outs = new BufferedWriter(new
OutputStreamWriter(new
FileOutputStream(saveCipherText.getSelectedFile().getPath()),"ASCII"));
outs.write(this.textAreaCipher.getText());
outs.close();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
JOptionPane.showMessageDialog(null, "Sukses Menyimpan
File "+saveCipherText.getSelectedFile().getName()+"\nLokasi File:
"+saveCipherText.getSelectedFile(),"CipherText Saved!",
JOptionPane.INFORMATION_MESSAGE);
}
else
JOptionPane.showMessageDialog(null, "Something
Happened?", "Gagal Menyimpan File", JOptionPane.ERROR_MESSAGE);
}
}//GEN-LAST:event_btnSaveCipherTextActionPerformed
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
BlowfishEnc dialog = new BlowfishEnc(new
javax.swing.JFrame(), true);
dialog.addWindowListener(new
java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent
e) {
System.exit(0);
}
});
dialog.setVisible(true);
}
});
}
/*
* BlowfishEnc.java
* @ Prasetyo Bawono
* @ jendalsepit@gmail.com
* nb: Semua konstruktor swing tidak disertakan.
* Full Source: http://ono.web.id/fugu
* Created on Apr 15, 2009, 8:30:05 AM
*/
package fugu.mode;
import fugu.FuguApp;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.jdesktop.application.Application;
import org.jdesktop.application.ResourceMap;
/**
*
* @author prasetyo bawono
*/
public class BlowfishDec extends javax.swing.JDialog {
Dimension screenSize =
Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = this.getSize();
this.setLocation((screenSize.width - frameSize.width) / 2,
(screenSize.height - frameSize.height) / 2);
this.setTitle("Decryption Mode");
// Define Clickable
textAreaPlain.setEnabled(false);
ResourceMap resourceMap =
Application.getInstance(fugu.FuguApp.class).getContext().getResourceMap(B
lowfishEnc.class);
textAreaPlain.setBackground(resourceMap.getColor("textAreaCipher.backgrou
nd"));
txtPassword.setEnabled(false);
btnResetPrivKey.setEnabled(false);
btnResetCipherText.setEnabled(false);
btnSaveCipherText.setEnabled(false);
btnOpenCipherText.setEnabled(true);
btnDecryptPlainText.setEnabled(false);
btnSavePlainText.setEnabled(false);
btnOpenCipherText.requestFocus();
}
private void
btnResetCipherTextActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
if (evt.getSource() == this.btnResetCipherText)
this.textAreaCipher.setText("");
this.textAreaPlain.setText("");
this.txtPassword.setText("");
btnResetCipherText.setEnabled(false);
btnSaveCipherText.setEnabled(false);
btnOpenCipherText.setEnabled(true);
btnDecryptPlainText.setEnabled(false);
txtPassword.setEnabled(false);
btnResetPrivKey.setEnabled(false);
btnSavePlainText.setEnabled(false);
textAreaPlain.setEnabled(false);
private void
btnSaveCipherTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-
FIRST:event_btnSaveCipherTextActionPerformed
// TODO add your handling code here:
if (evt.getSource() == this.btnSaveCipherText){
JFileChooser saveCipherText = new JFileChooser();
FileNameExtensionFilter filter = new
FileNameExtensionFilter(".cip CipherText File", "cip", "CIP");
saveCipherText.setFileFilter(filter);
saveCipherText.setDialogTitle("Save as CipherText");
int option = saveCipherText.showSaveDialog(this);
// Jika OK
if (option == JFileChooser.APPROVE_OPTION){
try {
// Buat buffered writer untuk menulis
BufferedWriter out = new BufferedWriter(new
FileWriter(saveCipherText.getSelectedFile().getPath()));
out.write(this.textAreaCipher.getText());
out.close();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
JOptionPane.showMessageDialog(null, "Sukses Menyimpan
File "+saveCipherText.getSelectedFile().getName()+"\nLokasi File:
"+saveCipherText.getSelectedFile(),"CipherText Saved!",
JOptionPane.INFORMATION_MESSAGE);
} else
JOptionPane.showMessageDialog(null, "Something
Happened?", "Gagal Menyimpan File", JOptionPane.ERROR_MESSAGE);
}
}//GEN-LAST:event_btnSaveCipherTextActionPerformed
private void
menuNotepadQuitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-
FIRST:event_menuNotepadQuitActionPerformed
// TODO add your handling code here:
FuguApp.getApplication().ShowMainMenu();
FuguApp.getInstanceMainMenu().setAuthentication(true);
this.dispose();
}//GEN-LAST:event_menuNotepadQuitActionPerformed
private void
btnOpenCipherTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-
FIRST:event_btnOpenCipherTextActionPerformed
if(openCipherText.showOpenDialog(this)==JFileChooser.APPROVE_OPTION){
File selectedFile =
openCipherText.getSelectedFile();
if (selectedFile.canRead() && selectedFile.exists())
{
FileInputStream fis = new
FileInputStream(selectedFile);
InputStreamReader in= new InputStreamReader(fis);
char[] buffer = new char[4194304];
int n = in.read(buffer);
String CipherText = new String(buffer,0,n);
textAreaCipher.setText(CipherText);
txtPassword.setEnabled(true);
btnResetPrivKey.setEnabled(true);
btnSaveCipherText.setEnabled(true);
btnOpenCipherText.setEnabled(false);
btnResetCipherText.setEnabled(true);
btnDecryptPlainText.setEnabled(true);
}//GEN-LAST:event_btnOpenCipherTextActionPerformed
private void
btnResetPrivKeyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-
FIRST:event_btnResetPrivKeyActionPerformed
// TODO add your handling code here:
if (evt.getSource() == this.btnResetPrivKey)
this.txtPassword.setText("");
}//GEN-LAST:event_btnResetPrivKeyActionPerformed
private void
btnDecryptPlainTextActionPerformed(java.awt.event.ActionEvent evt)
{//GEN-FIRST:event_btnDecryptPlainTextActionPerformed
// Decrypt:
// ========
// Cipher(String) -> Cipher(String->Byte Array[]) -> Plain(Byte
Array[]->String) -> Plain(String)
if(evt.getSource()==this.btnDecryptPlainText){
if (txtPassword!=null){
Security.addProvider(new
org.bouncycastle.jce.provider.BouncyCastleProvider());
textAreaPlain.setBackground(Color.WHITE);
textAreaPlain.setEnabled(true);
btnSavePlainText.setEnabled(true);
// ECB MODE
if (rbECB.isSelected()) {
try {
// Start Counting
long ecbStart;
long ecbEnd;
long ecbTime;
ecbStart = System.currentTimeMillis();
// Decryption
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] plainText =
cipher.doFinal(textCipherByte);
// CBC MODE
if (rbCBC.isSelected()) {
try {
// Start Counting
long cbcStart;
long cbcEnd;
long cbcTime;
cbcStart = System.currentTimeMillis();
// Inisialitazion Vector
byte[] ivBytes = new byte[]{
0x07, 0x06, 0x05, 0x04, 0x03,
0x02, 0x01, 0x00
};
// Decryption
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
byte[] plainText =
cipher.doFinal(textCipherByte);
// OFB MODE
if (rbOFB.isSelected()) {
try {
// Start Counting
long ofbStart;
long ofbEnd;
long ofbTime;
ofbStart = System.currentTimeMillis();
// Inisialitazion Vector
byte[] ivBytes = new byte[]{
0x07, 0x06, 0x05, 0x04, 0x03,
0x02, 0x01, 0x00
};
// Decryption
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
byte[] plainText =
cipher.doFinal(textCipherByte);
// CFB MODE
if (rbCFB.isSelected()) {
try {
// Start Counting
long cfbStart;
long cfbEnd;
long cfbTime;
cfbStart = System.currentTimeMillis();
// Inisialitazion Vector
byte[] ivBytes = new byte[]{
0x07, 0x06, 0x05, 0x04, 0x03,
0x02, 0x01, 0x00
};
// Decryption
btnResetPrivKey.setEnabled(false);;
txtPassword.setEnabled(false);
}
}//GEN-LAST:event_btnDecryptPlainTextActionPerformed
private void
btnSavePlainTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-
FIRST:event_btnSavePlainTextActionPerformed
// TODO add your handling code here:
if (evt.getSource() == this.btnSavePlainText){
JFileChooser savePlainText = new JFileChooser();
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
BlowfishDec dialog = new BlowfishDec(new
javax.swing.JFrame(), true);
dialog.addWindowListener(new
java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent
e) {
System.exit(0);
}
});
dialog.setVisible(true);
}
});
}
package fugu.dbase;
import java.sql.*;
//Constructor
public DriverConnection(){
}
try {
Class.forName(driverName);
conn = DriverManager.getConnection(currentUrl, userId, password);
isConnect=true;
}
catch(ClassNotFoundException cnfe)
{
System.err.println(cnfe);
}
catch(SQLException sqle)
{
conn=null;
isConnect=false;
System.err.println(sqle);
}
}
if (conn !=null)
return conn;
else //Try again
{
init();
return conn;
}
}
conn.close();
}
}
package org.bouncycastle.crypto.engines;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.params.KeyParameter;
/**
* Kelas untuk operasi kunci Blowfish.
* Seperti encoding data dan meng-generate kunci
* Semua algoritma yang ada bersumber dari buku Applied Cryptography
*
*/
},
KS1 = {
0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623,
0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266,
0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E,
0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6,
0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E,
0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1,
0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8,
0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF,
0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701,
0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7,
0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331,
0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF,
0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E,
0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87,
0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2,
0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16,
0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B,
0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509,
0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3,
0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F,
0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4,
0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960,
0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28,
0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802,
0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510,
0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF,
0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E,
0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50,
0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8,
0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281,
0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
KS2 = {
0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934,
0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068,
0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840,
0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45,
0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A,
0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB,
0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6,
0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42,
0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2,
0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB,
0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B,
0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33,
0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3,
0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC,
0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564,
0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B,
0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922,
0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728,
KS3 = {
0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B,
0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE,
0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4,
0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8,
0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304,
//====================================
// Useful constants
//====================================
public BlowfishEngine()
{
S0 = new int[SBOX_SK];
S1 = new int[SBOX_SK];
S2 = new int[SBOX_SK];
S3 = new int[SBOX_SK];
P = new int[P_SZ];
}
/**
* initialise a Blowfish cipher.
*
* @param encrypting whether or not we are for encryption.
* @param params the parameters required to set up the cipher.
* @exception IllegalArgumentException if the params argument is
* inappropriate.
*/
public void init(
boolean encrypting,
CipherParameters params)
{
return;
}
if (encrypting)
{
encryptBlock(in, inOff, out, outOff);
}
else
{
decryptBlock(in, inOff, out, outOff);
}
return BLOCK_SIZE;
}
//==================================
// Private Implementation
//==================================
/**
* apply the encryption cycle to each value pair in the table.
*/
private void processTable(
int xl,
int xr,
int[] table)
{
int size = table.length;
xr ^= P[ROUNDS + 1];
table[s] = xr;
table[s + 1] = xl;
xl = table[s];
}
}
System.arraycopy(KP, 0, P, 0, P_SZ);
/*
* (2)
* Now, XOR P[0] with the first 32 bits of the key, XOR P[1] with
the
* second 32-bits of the key, and so on for all bits of the key
* (up to P[17]). Repeatedly cycle through the key bits until
the
* entire P-array has been XOR-ed with the key bits
*/
int keyLength = key.length;
int keyIndex = 0;
}
// XOR the newly created 32 bit chunk onto the P-array
P[i] ^= data;
}
/*
* (3)
* Encrypt the all-zero string with the Blowfish algorithm, using
* the subkeys described in (1) and (2)
*
* (4)
* Replace P1 and P2 with the output of step (3)
*
* (5)
* Encrypt the output of step(3) using the Blowfish algorithm,
* with the modified subkeys.
*
* (6)
* Replace P3 and P4 with the output of step (5)
*
* (7)
* Continue the process, replacing all elements of the P-array
* and then all four S-boxes in order, with the output of the
* continuously changing Blowfish algorithm
*/
processTable(0, 0, P);
processTable(P[P_SZ - 2], P[P_SZ - 1], S0);
processTable(S0[SBOX_SK - 2], S0[SBOX_SK - 1], S1);
processTable(S1[SBOX_SK - 2], S1[SBOX_SK - 1], S2);
processTable(S2[SBOX_SK - 2], S2[SBOX_SK - 1], S3);
}
/**
* Encrypt the given input starting at the given offset and place
* the result in the provided buffer starting at the given offset.
* The input will be an exact multiple of our blocksize.
*/
private void encryptBlock(
byte[] src,
int srcIndex,
byte[] dst,
int dstIndex)
{
int xl = BytesTo32bits(src, srcIndex);
int xr = BytesTo32bits(src, srcIndex+4);
xl ^= P[0];
xr ^= P[ROUNDS + 1];
/**
* Decrypt the given input starting at the given offset and place
* the result in the provided buffer starting at the given offset.
* The input will be an exact multiple of our blocksize.
*/
private void decryptBlock(
byte[] src,
int srcIndex,
byte[] dst,
int dstIndex)
{
int xl = BytesTo32bits(src, srcIndex);
int xr = BytesTo32bits(src, srcIndex + 4);
xl ^= P[ROUNDS + 1];
xr ^= P[0];
package org.bouncycastle.crypto.modes;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.util.Arrays;
/**
* implements Cipher-Block-Chaining (CBC) mode on top of a simple cipher.
*/
public class CBCBlockCipher
implements BlockCipher
{
private byte[] IV;
private byte[] cbcV;
private byte[] cbcNextV;
/**
* Basic constructor.
*
* @param cipher the block cipher to be used as the basis of
chaining.
*/
public CBCBlockCipher(
BlockCipher cipher)
{
this.cipher = cipher;
this.blockSize = cipher.getBlockSize();
/**
* return the underlying block cipher that we are wrapping.
*
* @return the underlying block cipher that we are wrapping.
*/
/**
* Initialise the cipher and, possibly, the initialisation vector
(IV).
* If an IV isn't passed as part of the parameter, the IV will be all
zeros.
*
* @param encrypting if true the cipher is initialised for
* encryption, if false for decryption.
* @param params the key and other data required by the cipher.
* @exception IllegalArgumentException if the params argument is
* inappropriate.
*/
public void init(
boolean encrypting,
CipherParameters params)
throws IllegalArgumentException
{
this.encrypting = encrypting;
if (iv.length != blockSize)
{
throw new IllegalArgumentException("initialisation
vector must be the same length as block size");
}
reset();
cipher.init(encrypting, ivParam.getParameters());
}
else
{
reset();
cipher.init(encrypting, params);
}
}
/**
* return the algorithm name and mode.
*
* @return the name of the underlying algorithm followed by "/CBC".
*/
public String getAlgorithmName()
{
return cipher.getAlgorithmName() + "/CBC";
}
/**
* return the block size of the underlying cipher.
*
* @return the block size of the underlying cipher.
*/
public int getBlockSize()
{
return cipher.getBlockSize();
}
/**
* Process one block of input from the array in and write it to
* the out array.
*
* @param in the array containing the input data.
* @param inOff offset into the in array the data starts at.
* @param out the array the output data will be copied into.
* @param outOff the offset into the out array the output will start
at.
* @exception DataLengthException if there isn't enough data in in,
or
* space in out.
* @exception IllegalStateException if the cipher isn't initialised.
* @return the number of bytes processed and produced.
*/
public int processBlock(
byte[] in,
int inOff,
byte[] out,
int outOff)
throws DataLengthException, IllegalStateException
{
return (encrypting) ? encryptBlock(in, inOff, out, outOff) :
decryptBlock(in, inOff, out, outOff);
}
/**
* reset the chaining vector back to the IV and reset the underlying
* cipher.
*/
public void reset()
{
System.arraycopy(IV, 0, cbcV, 0, IV.length);
Arrays.fill(cbcNextV, (byte)0);
cipher.reset();
}
/**
* Do the appropriate chaining step for CBC mode encryption.
*
* @param in the array containing the data to be encrypted.
* @param inOff offset into the in array the data starts at.
* @param out the array the encrypted data will be copied into.
* @param outOff the offset into the out array the output will start
at.
* @exception DataLengthException if there isn't enough data in in,
or
* space in out.
* @exception IllegalStateException if the cipher isn't initialised.
* @return the number of bytes processed and produced.
*/
private int encryptBlock(
byte[] in,
int inOff,
byte[] out,
int outOff)
throws DataLengthException, IllegalStateException
{
if ((inOff + blockSize) > in.length)
{
throw new DataLengthException("input buffer too short");
}
/*
* XOR the cbcV and the input,
* then encrypt the cbcV
*/
for (int i = 0; i < blockSize; i++)
{
cbcV[i] ^= in[inOff + i];
}
/*
* copy ciphertext to cbcV
*/
System.arraycopy(out, outOff, cbcV, 0, cbcV.length);
return length;
}
/**
* Do the appropriate chaining step for CBC mode decryption.
*
* @param in the array containing the data to be decrypted.
* @param inOff offset into the in array the data starts at.
* @param out the array the decrypted data will be copied into.
* @param outOff the offset into the out array the output will start
at.
* @exception DataLengthException if there isn't enough data in in,
or
* space in out.
* @exception IllegalStateException if the cipher isn't initialised.
* @return the number of bytes processed and produced.
*/
private int decryptBlock(
byte[] in,
int inOff,
byte[] out,
int outOff)
throws DataLengthException, IllegalStateException
{
if ((inOff + blockSize) > in.length)
{
throw new DataLengthException("input buffer too short");
}
/*
* XOR the cbcV and the output
*/
for (int i = 0; i < blockSize; i++)
{
out[outOff + i] ^= cbcV[i];
}
/*
* swap the back up buffer into next position
*/
byte[] tmp;
tmp = cbcV;
cbcV = cbcNextV;
cbcNextV = tmp;
return length;
}
}
package org.bouncycastle.crypto.modes;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.params.ParametersWithIV;
/**
* implements a Cipher-FeedBack (CFB) mode on top of a simple cipher.
*/
public class CFBBlockCipher
implements BlockCipher
{
private byte[] IV;
private byte[] cfbV;
private byte[] cfbOutV;
/**
* Basic constructor.
*
* @param cipher the block cipher to be used as the basis of the
* feedback mode.
* @param bitBlockSize the block size in bits (note: a multiple of 8)
*/
public CFBBlockCipher(
BlockCipher cipher,
int bitBlockSize)
{
this.cipher = cipher;
this.blockSize = bitBlockSize / 8;
/**
* return the underlying block cipher that we are wrapping.
*
* @return the underlying block cipher that we are wrapping.
*/
public BlockCipher getUnderlyingCipher()
{
return cipher;
}
/**
* Initialise the cipher and, possibly, the initialisation vector
(IV).
* If an IV isn't passed as part of the parameter, the IV will be all
zeros.
* An IV which is too short is handled in FIPS compliant fashion.
*
* @param encrypting if true the cipher is initialised for
* encryption, if false for decryption.
* @param params the key and other data required by the cipher.
* @exception IllegalArgumentException if the params argument is
* inappropriate.
*/
public void init(
boolean encrypting,
CipherParameters params)
throws IllegalArgumentException
{
this.encrypting = encrypting;
reset();
cipher.init(true, ivParam.getParameters());
}
else
{
reset();
cipher.init(true, params);
}
}
/**
* return the algorithm name and mode.
*
* @return the name of the underlying algorithm followed by "/CFB"
* and the block size in bits.
*/
public String getAlgorithmName()
{
return cipher.getAlgorithmName() + "/CFB" + (blockSize * 8);
}
/**
* return the block size we are operating at.
*
* @return the block size we are operating at (in bytes).
*/
public int getBlockSize()
{
return blockSize;
}
/**
* Process one block of input from the array in and write it to
* the out array.
*
* @param in the array containing the input data.
* @param inOff offset into the in array the data starts at.
* @param out the array the output data will be copied into.
* @param outOff the offset into the out array the output will start
at.
* @exception DataLengthException if there isn't enough data in in,
or
* space in out.
* @exception IllegalStateException if the cipher isn't initialised.
* @return the number of bytes processed and produced.
*/
public int processBlock(
byte[] in,
int inOff,
byte[] out,
int outOff)
throws DataLengthException, IllegalStateException
{
return (encrypting) ? encryptBlock(in, inOff, out, outOff) :
decryptBlock(in, inOff, out, outOff);
}
/**
* Do the appropriate processing for CFB mode encryption.
*
* @param in the array containing the data to be encrypted.
* @param inOff offset into the in array the data starts at.
* @param out the array the encrypted data will be copied into.
* @param outOff the offset into the out array the output will start
at.
* @exception DataLengthException if there isn't enough data in in,
or
* space in out.
* @exception IllegalStateException if the cipher isn't initialised.
* @return the number of bytes processed and produced.
*/
public int encryptBlock(
byte[] in,
int inOff,
byte[] out,
int outOff)
throws DataLengthException, IllegalStateException
{
if ((inOff + blockSize) > in.length)
{
throw new DataLengthException("input buffer too short");
}
//
// XOR the cfbV with the plaintext producing the ciphertext
//
for (int i = 0; i < blockSize; i++)
{
//
// change over the input block.
//
System.arraycopy(cfbV, blockSize, cfbV, 0, cfbV.length -
blockSize);
System.arraycopy(out, outOff, cfbV, cfbV.length - blockSize,
blockSize);
return blockSize;
}
/**
* Do the appropriate processing for CFB mode decryption.
*
* @param in the array containing the data to be decrypted.
* @param inOff offset into the in array the data starts at.
* @param out the array the encrypted data will be copied into.
* @param outOff the offset into the out array the output will start
at.
* @exception DataLengthException if there isn't enough data in in,
or
* space in out.
* @exception IllegalStateException if the cipher isn't initialised.
* @return the number of bytes processed and produced.
*/
public int decryptBlock(
byte[] in,
int inOff,
byte[] out,
int outOff)
throws DataLengthException, IllegalStateException
{
if ((inOff + blockSize) > in.length)
{
throw new DataLengthException("input buffer too short");
}
//
//
// XOR the cfbV with the ciphertext producing the plaintext
//
for (int i = 0; i < blockSize; i++)
{
out[outOff + i] = (byte)(cfbOutV[i] ^ in[inOff + i]);
}
return blockSize;
}
/**
* reset the chaining vector back to the IV and reset the underlying
* cipher.
*/
public void reset()
{
System.arraycopy(IV, 0, cfbV, 0, IV.length);
cipher.reset();
}
}
package org.bouncycastle.crypto.modes;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.params.ParametersWithIV;
/**
* implements a Output-FeedBack (OFB) mode on top of a simple cipher.
*/
public class OFBBlockCipher
implements BlockCipher
{
private byte[] IV;
private byte[] ofbV;
private byte[] ofbOutV;
/**
* Basic constructor.
*
* @param cipher the block cipher to be used as the basis of the
* feedback mode.
* @param blockSize the block size in bits (note: a multiple of 8)
*/
public OFBBlockCipher(
BlockCipher cipher,
int blockSize)
{
this.cipher = cipher;
this.blockSize = blockSize / 8;
/**
* return the underlying block cipher that we are wrapping.
*
* @return the underlying block cipher that we are wrapping.
*/
/**
* Initialise the cipher and, possibly, the initialisation vector
(IV).
* If an IV isn't passed as part of the parameter, the IV will be all
zeros.
* An IV which is too short is handled in FIPS compliant fashion.
*
* @param encrypting if true the cipher is initialised for
* encryption, if false for decryption.
* @param params the key and other data required by the cipher.
* @exception IllegalArgumentException if the params argument is
* inappropriate.
*/
public void init(
boolean encrypting, //ignored by this OFB mode
CipherParameters params)
throws IllegalArgumentException
{
if (params instanceof ParametersWithIV)
{
ParametersWithIV ivParam = (ParametersWithIV)params;
byte[] iv = ivParam.getIV();
reset();
cipher.init(true, ivParam.getParameters());
}
else
{
reset();
cipher.init(true, params);
}
}
/**
* return the algorithm name and mode.
*
* @return the name of the underlying algorithm followed by "/OFB"
* and the block size in bits
*/
public String getAlgorithmName()
{
return cipher.getAlgorithmName() + "/OFB" + (blockSize * 8);
}
/**
* return the block size we are operating at (in bytes).
*
* @return the block size we are operating at (in bytes).
*/
public int getBlockSize()
{
return blockSize;
}
/**
* Process one block of input from the array in and write it to
* the out array.
*
* @param in the array containing the input data.
* @param inOff offset into the in array the data starts at.
* @param out the array the output data will be copied into.
* @param outOff the offset into the out array the output will start
at.
* @exception DataLengthException if there isn't enough data in in,
or
* space in out.
* @exception IllegalStateException if the cipher isn't initialised.
* @return the number of bytes processed and produced.
*/
public int processBlock(
byte[] in,
int inOff,
byte[] out,
int outOff)
throws DataLengthException, IllegalStateException
{
if ((inOff + blockSize) > in.length)
{
throw new DataLengthException("input buffer too short");
}
//
// XOR the ofbV with the plaintext producing the cipher text (and
// the next input block).
//
for (int i = 0; i < blockSize; i++)
{
out[outOff + i] = (byte)(ofbOutV[i] ^ in[inOff + i]);
}
//
// change over the input block.
//
System.arraycopy(ofbV, blockSize, ofbV, 0, ofbV.length -
blockSize);
System.arraycopy(ofbOutV, 0, ofbV, ofbV.length - blockSize,
blockSize);
return blockSize;
}
/**
* reset the feedback vector back to the IV and reset the underlying
* cipher.
*/
public void reset()
{
System.arraycopy(IV, 0, ofbV, 0, IV.length);
cipher.reset();
}
}