Analisis Kode Implementasi Steganografi LSB

Dokumen ini memberikan penjelasan teknis mengenai kode JavaScript yang digunakan untuk mendemonstrasikan proses penyembunyian (encoding) dan ekstraksi (decoding) pesan menggunakan metode Steganografi LSB (Least Significant Bit).

Implementasi ini memanfaatkan HTML5 Canvas API untuk memanipulasi data piksel gambar secara langsung di browser.

Konsep Dasar & Teknologi

Steganografi

Berbeda dengan kriptografi yang mengunci isi pesan, steganografi adalah seni menyembunyikan keberadaan pesan itu sendiri. Tujuannya adalah untuk menyisipkan data rahasia ke dalam sebuah media pembawa (dalam kasus ini, gambar) tanpa menimbulkan perubahan yang dapat dideteksi secara visual.

Metode LSB (Least Significant Bit)

Ini adalah salah satu teknik steganografi yang paling umum. Prinsipnya adalah memodifikasi bit yang memiliki dampak paling kecil pada nilai total data piksel. Setiap piksel dalam gambar terdiri dari komponen warna RGB. Dengan mengubah bit terakhir dari setiap nilai warna (misal: dari 10101101 menjadi 10101100), kita bisa menyisipkan satu bit pesan tanpa mengubah warna piksel secara signifikan.

HTML5 Canvas API

Ini adalah antarmuka bawaan browser yang memungkinkan kita untuk menggambar dan memanipulasi grafik—termasuk gambar—secara dinamis. Kita menggunakannya untuk "membaca" data piksel dari gambar asli dan "menulis" kembali data piksel yang sudah dimodifikasi.

Sentinel (Penanda Akhir)

Untuk mengetahui di mana pesan rahasia berakhir saat proses ekstraksi, kita menambahkan serangkaian bit khusus yang unik di akhir pesan. Dalam kode ini, penandanya adalah 11111111111111110000000000000000. Saat proses ekstraksi menemukan pola ini, ia tahu bahwa pesan telah selesai dibaca.

Elemen HTML Terkait dan Fungsinya

Berikut adalah peran setiap elemen HTML di dalam antarmuka demo Steganografi.

Elemen (ID) Tipe Fungsi / Deskripsi
Kolom Penyembunyian Pesan
#stego-secret-text textarea Area input untuk memasukkan pesan rahasia.
#cover-image input type="file" Tombol untuk mengunggah gambar sampul (media penyembunyi).
#stego-encode-btn button Pemicu untuk menjalankan proses penyembunyian (encoding).
#stego-encode-result div Kontainer untuk menampilkan gambar hasil dan tombol unduh.
Kolom Ekstraksi Pesan
#image-to-decode input type="file" Tombol untuk mengunggah gambar yang berisi pesan tersembunyi.
#stego-decode-btn button Pemicu untuk menjalankan proses ekstraksi (decoding).
#stego-decode-result div Kontainer untuk menampilkan pesan yang berhasil diekstrak.

Analisis Kode Proses Penyembunyian (Encoding)

Fungsi `strToBinary(str)`

Fungsi utilitas ini mengubah sebuah string teks menjadi representasi biner yang siap disisipkan ke dalam gambar.

const strToBinary = (str) => 
  str.split('').map(c => 
    c.charCodeAt(0).toString(2).padStart(8, '0')
  ).join('');

Event Listener Tombol Penyembunyian

Kode ini berjalan saat tombol #stego-encode-btn diklik.

stegoEncodeBtn.addEventListener('click', () => {
const text = stegoSecretText.value;
const file = coverImageInput.files[0];
if (!text || !file) { /* ... handle error ... */ }

const reader = new FileReader();
reader.onload = (e) => {
    const img = new Image();
    img.onload = () => {
        // 1. Siapkan Canvas dan gambar asli
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        canvas.width = img.width; canvas.height = img.height;
        ctx.drawImage(img, 0, 0);

        // 2. Siapkan pesan biner dengan penanda akhir
        const binaryMessage = strToBinary(text) + sentinel;
        const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
        
        // Cek apakah pesan muat di dalam gambar
        if (binaryMessage.length > (imageData.data.length / 4 * 3)) {
                return showToast("Pesan terlalu besar untuk gambar.");
        }

        // 3. Proses Penyisipan LSB
        for (let i = 0; i < binaryMessage.length; i++) {
            // Tentukan indeks data piksel yang akan dimodifikasi (R, G, atau B)
            const dataIndex = Math.floor(i / 3) * 4 + (i % 3);
            // Ubah LSB dari komponen warna dengan bit dari pesan
            imageData.data[dataIndex] = (imageData.data[dataIndex] & 0xFE) 
            | parseInt(binaryMessage[i]);
        }

        // 4. Tulis data piksel yang sudah dimodifikasi dan tampilkan hasil
        ctx.putImageData(imageData, 0, 0);
        const stegoDataURL = canvas.toDataURL('image/png');
        document.getElementById('stego-image').src = stegoDataURL;
        // ... tampilkan hasil ke UI ...
    };
    img.src = e.target.result;
};
reader.readAsDataURL(file);
});

Alur Proses Encoding:

  1. Membaca Gambar: FileReader membaca file gambar dan mengubahnya menjadi URL data.
  2. Menggambar ke Canvas: Gambar dimuat dan digambar ke elemen <canvas> untuk mengakses data pikselnya.
  3. Proses Penyisipan: Sebuah for loop berjalan untuk setiap bit dari pesan. Bit pesan disisipkan ke dalam Least Significant Bit (LSB) dari setiap komponen warna (R, G, B) secara berurutan.
  4. Menampilkan Hasil: Data piksel yang telah dimodifikasi ditulis kembali ke canvas, lalu diubah menjadi URL data gambar baru untuk ditampilkan dan diunduh.

Analisis Kode Proses Ekstraksi (Decoding)

Event Listener Tombol Ekstraksi

Proses ini terjadi ketika pengguna menekan tombol #stego-decode-btn.

document.getElementById('stego-decode-btn').addEventListener('click', () => {
const file = document.getElementById('image-to-decode').files[0];
if (!file) { /* ... handle error ... */ }

const reader = new FileReader();
reader.onload = (e) => {
const img = new Image();
img.onload = () => {
    // 1. Siapkan Canvas dan data piksel dari gambar
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    canvas.width = img.width; canvas.height = img.height;
    ctx.drawImage(img, 0, 0);
    const data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
    
    // 2. Ekstrak bit dari setiap komponen warna
    let binaryMessage = '';
    for (let i = 0; i < data.length; i++) {
        if ((i + 1) % 4 !== 0) { // Lewati komponen Alpha (A)
            binaryMessage += (data[i] & 1).toString();
        }
        
        // 3. Hentikan jika penanda akhir (sentinel) ditemukan
        if (binaryMessage.endsWith(sentinel)) break;
    }

    // 4. Proses dan tampilkan hasil jika sentinel ditemukan
    const sentinelIndex = binaryMessage.indexOf(sentinel);
    if (sentinelIndex !== -1) {
        const hiddenBinary = binaryMessage.substring(0, sentinelIndex);
         // 'binaryToStr' is the reverse of 'strToBinary'
        const decodedMessage = binaryToStr(hiddenBinary);
        document.getElementById('decoded-message').textContent = decodedMessage;
        // ... tampilkan hasil ke UI ...
    } else {
        showToast("Tidak ada pesan tersembunyi yang ditemukan.");
    }
};
img.src = e.target.result;
};
reader.readAsDataURL(file);
});

Alur Proses Decoding:

  1. Membaca Gambar: Sama seperti proses encoding, gambar yang diunggah dibaca dan digambar ke canvas.
  2. Proses Ekstraksi: Sebuah for loop berjalan melalui data piksel gambar. Dari setiap komponen warna (R, G, B), LSB-nya diekstrak (data[i] & 1) dan digabungkan menjadi sebuah string biner.
  3. Mencari Penanda Akhir: Setelah setiap bit ditambahkan, kode memeriksa apakah string biner tersebut diakhiri dengan pola sentinel. Jika ya, loop berhenti.
  4. Menampilkan Pesan: Jika sentinel ditemukan, string biner sebelum sentinel diubah kembali menjadi teks dan ditampilkan kepada pengguna.

Kesimpulan

Implementasi ini secara efektif menunjukkan konsep steganografi LSB di lingkungan web modern.

  • Manipulasi Langsung: Dengan Canvas API, kita dapat memanipulasi data gambar pada tingkat piksel secara langsung di browser tanpa memerlukan *library* eksternal.
  • Kapasitas vs. Ketidakterlihatan: Metode LSB menawarkan keseimbangan yang baik antara kapasitas penyembunyian data dan perubahan visual yang minimal (hampir tidak terlihat oleh mata manusia).
  • Pentingnya Penanda: Penggunaan sentinel adalah teknik krusial dan sederhana untuk menandai akhir dari data yang disembunyikan, memungkinkan ekstraksi yang akurat.