Enkripsi pada umumnya tersusun dari 3 jenis data yaitu plaintext, key, dan ciphertext. Plaintext bisa dianggap sebagai sebuah pesan asli. Ciphertext bisa dianggap sebagai hasil jadi dari pesan yang telah dienkripsi. Key bisa dianggap sebagai unsur atau kunci yang mempengaruhi hasil jadi ciphertext.
Seorang pimpinan pasukan tentara bernama Joseph Mauborgne mengusulkan adanya peningkatan pada algoritme enkripsi Vernam Cipher. Mauborgne mengusulkan sebuah konsep bernama One-Time Pad yang mengatur bahwa key dibuat secara acak, sehingga tidak ada pengulangan penggunaan key. Jadi, key akan dibuang ketika sudah dipakai untuk proses enkripsi atau dekripsi. Selain itu panjang key dibuat sama dengan panjang plaintext.
Caption: kumpulan angka biner dalam enkripsi

Source: pixabay geralt
Berikut ini rumus enkripsi Vernam Cipher:
Ciphertext = Angka biner dari Plaintext dilakukan XOR dengan angka biner dari Key
Plaintext = Angka biner dari Ciphertext dilakukan XOR dengan angka biner dari Key
[size=h2]2 Alasan kenapa Vernam Cipher tidak mungkin dipecahkan[/size]
1. Ciphertext tidak memiliki karakteristik yang unik
Pada umumnya, ciphertext pada algoritme enkripsi memiliki karakteristik yang unik sehingga bisa dihasilkan sebuah kumpulan statistik. Vernam Cipher tidak memiliki karakteristik khusus dan ciphertext tidak memiliki hubungan statistik yang unik. Angka biner terdiri dari sekumpulan angka nol dan satu. Sekumpulin angka biner antara plaintext, key, dan ciphertext pada Vernam Cipher memiliki karakteristik yang sama. Tidak adanya perbedaan karakteristik membuat peretas keamanan kesulitan untuk menghasilkan perbedaan statistik pada setiap chipertext.Contoh karakteristik dari algoritma enkripsi Caesar Cipher:
Ciphertext: dnx vxnd ndpx
Dari contoh ciphertext caesar cipher di atas dapat diidentifikasi bahwa ciphertext terdiri dari 3 kata yang ditandai dengan adanya spasi sebagai pemisah kata. Kata pertama terdiri dari 3 karakter, kata kedua terdiri dari 4 karakter, kata ketiga juga terdiri dari 4 karakter. Pada Vernam Cipher, setiap chipertext tidak dapat diidentifikasi karena nantinya tidak hanya karakter huruf alfabet saja yang dienkripsi. Pada Vernam CIpher, seluruh karakter lain seperti spasi, tanda titik, dan lain sebagainya juga akan dilakukan enkripsi karena juga memiliki kode biner yang berbeda.
2. Hasil ciphertext tidak unik
Pada umumnya, setiap algoritme enkripsi memiliki ciphertext yang unik. Dengan kata lain bahwa 1 ciphertext hanya bisa dihasilkan dari 1 permutasi plaintext dan key. Pada algoritme vernam cipher, ciphertext bisa dihasilkan dari banyak permutasi sehingga sulit untuk menentukan key yang sesungguhnya digunakan. Panjang plaintext dan key adalah sama sehingga bisa juga dikatakan bahwa panjang ciphertext juga sama.Contoh karakteristik yang sama pada biner Vernam Cipher:
1 XOR 0 = 1
0 XOR 1 = 1
1 XOR 1 = 0
0 XOR 0 = 0
Jadi 1 angka biner bisa dihasilkan dari 2 permutasi. Jika menggunakan biner 8 bit maka total permutasi angka biner yaitu 256 (2 pangkat 8). Plaintext, key dan ciphertext memiliki karakteristik yang sama. Jika dimisalkan ciphertext terdiri dari 8 bit biner dapat dihasilkan dari 256 permutasi maka itu berlaku juga pada key dan plaintext.
Di bawah ini merupakan contoh source code enkripsi dan source code bruteforce dekripsi Vernam Cipher menggunakan bahasa pemrograman PHP.
Enkripsi Vernam Cipher
<?php
$plaintext="01100001";//ganti dengan biner plaintext yang diinginkan
$key="01100011";//ganti dengan biner key yang diinginkan
$ciphertext="";
for($i=0;$i<strlen($plaintext);$i++){
$temp=(int)$plaintext[$i]^(int)$key[$i];
$ciphertext.=$temp;
}
echo $ciphertext."\n";//00000010
?>
Jika kode di atas dijalankan di terminal maka akan menampilkan output yaitu "00000010" yang didapatkan dari hasil XOR antara "01100001" dan "01100011".
Bruteforce Vernam Cipher
<?php
//fungsi untuk generate seluruh permutasi biner 8 bit (2 pangkat 8) dan mengecualikan biner dari ciphertext
function get_kemungkinan_key($ciphertext){
$biner=Array("0","1");
$hasil=Array();
$panjang=count($biner);
for($a=0;$a<$panjang;$a++){
for($b=0;$b<$panjang;$b++){
for($c=0;$c<$panjang;$c++){
for($d=0;$d<$panjang;$d++){
for($e=0;$e<$panjang;$e++){
for($f=0;$f<$panjang;$f++){
for($g=0;$g<$panjang;$g++){
for($h=0;$h<$panjang;$h++){
$val=$biner[$a].$biner[$b].$biner[$c].$biner[$d].$biner[$e].$biner[$f].$biner[$g].$biner[$h];
if($val!==$ciphertext){
array_push($hasil,$val);
}
}
}
}
}
}
}
}
}
return $hasil;
}
$ciphertext="00000010";//ganti dengan biner ciphertext yang diinginkan
$key=get_kemungkinan_key("");
$plaintext=get_kemungkinan_key($ciphertext);
$hasil=Array();
$kemungkinan_key=Array();
$kemungkinan_plaintext=Array();
foreach($key as $k=>$vk){
foreach($plaintext as $p=>$vp){
$vernam="";
for($i=0;$i<strlen($ciphertext);$i++){
$temp=(int)$vk[$i]^(int)$vp[$i];
$vernam.=$temp;
}
$decimal_k=bindec($vk);
$hexa_k=dechex($decimal_k);
$asci_k=chr($decimal_k);
$decimal_p=bindec($vp);
$hexa_p=dechex($decimal_p);
$asci_p=chr($decimal_p);
if($vernam==$ciphertext){
array_push($hasil,$vernam);
if($vk!=$ciphertext){
array_push($kemungkinan_key,$vk);
}
if($vp!=$ciphertext){
array_push($kemungkinan_plaintext,$vp);
}
// echo $vk."(".$asci_k.") ^ ".$vp."(".$asci_p.") = ".$vernam."\n";
echo $vk." ^ ".$vp." = ".$vernam."\n";
}
}
}
?>
Jika kode di atas dijalankan di terminal maka akan menampilkan seluruh kemungkinan untuk menghasilkan ciphertext tersebut. Karena kemungkinan yang dihasilkan begitu banyak sesuai panjang ciphertext maka dapat mengakibatkan para peretas mengalami kesulitan untuk menentukan key mana yang dimaksud.
Ini contoh hasilnya:
00000001 ^ 00000011 = 00000010
00000010 ^ 00000000 = 00000010
00000011 ^ 00000001 = 00000010
00000100 ^ 00000110 = 00000010
00000101 ^ 00000111 = 00000010
00000110 ^ 00000100 = 00000010
00000111 ^ 00000101 = 00000010
00001000 ^ 00001010 = 00000010
00001001 ^ 00001011 = 00000010
00001010 ^ 00001000 = 00000010
00001011 ^ 00001001 = 00000010
00001100 ^ 00001110 = 00000010
00001101 ^ 00001111 = 00000010
00001110 ^ 00001100 = 00000010
00001111 ^ 00001101 = 00000010
00010000 ^ 00010010 = 00000010
00010001 ^ 00010011 = 00000010
00010010 ^ 00010000 = 00000010
00010011 ^ 00010001 = 00000010
00010100 ^ 00010110 = 00000010
00010101 ^ 00010111 = 00000010
00010110 ^ 00010100 = 00000010
00010111 ^ 00010101 = 00000010
00011000 ^ 00011010 = 00000010
00011001 ^ 00011011 = 00000010
00011010 ^ 00011000 = 00000010
00011011 ^ 00011001 = 00000010
00011100 ^ 00011110 = 00000010
00011101 ^ 00011111 = 00000010
00011110 ^ 00011100 = 00000010
00011111 ^ 00011101 = 00000010
00100000 ^ 00100010 = 00000010
00100001 ^ 00100011 = 00000010
00100010 ^ 00100000 = 00000010
00100011 ^ 00100001 = 00000010
00100100 ^ 00100110 = 00000010
00100101 ^ 00100111 = 00000010
00100110 ^ 00100100 = 00000010
00100111 ^ 00100101 = 00000010
00101000 ^ 00101010 = 00000010
00101001 ^ 00101011 = 00000010
00101010 ^ 00101000 = 00000010
00101011 ^ 00101001 = 00000010
00101100 ^ 00101110 = 00000010
00101101 ^ 00101111 = 00000010
00101110 ^ 00101100 = 00000010
00101111 ^ 00101101 = 00000010
00110000 ^ 00110010 = 00000010
00110001 ^ 00110011 = 00000010
00110010 ^ 00110000 = 00000010
00110011 ^ 00110001 = 00000010
00110100 ^ 00110110 = 00000010
00110101 ^ 00110111 = 00000010
00110110 ^ 00110100 = 00000010
00110111 ^ 00110101 = 00000010
00111000 ^ 00111010 = 00000010
00111001 ^ 00111011 = 00000010
00111010 ^ 00111000 = 00000010
00111011 ^ 00111001 = 00000010
00111100 ^ 00111110 = 00000010
00111101 ^ 00111111 = 00000010
00111110 ^ 00111100 = 00000010
00111111 ^ 00111101 = 00000010
01000000 ^ 01000010 = 00000010
01000001 ^ 01000011 = 00000010
01000010 ^ 01000000 = 00000010
01000011 ^ 01000001 = 00000010
01000100 ^ 01000110 = 00000010
01000101 ^ 01000111 = 00000010
01000110 ^ 01000100 = 00000010
01000111 ^ 01000101 = 00000010
01001000 ^ 01001010 = 00000010
01001001 ^ 01001011 = 00000010
01001010 ^ 01001000 = 00000010
01001011 ^ 01001001 = 00000010
01001100 ^ 01001110 = 00000010
01001101 ^ 01001111 = 00000010
01001110 ^ 01001100 = 00000010
01001111 ^ 01001101 = 00000010
01010000 ^ 01010010 = 00000010
01010001 ^ 01010011 = 00000010
01010010 ^ 01010000 = 00000010
01010011 ^ 01010001 = 00000010
01010100 ^ 01010110 = 00000010
01010101 ^ 01010111 = 00000010
01010110 ^ 01010100 = 00000010
01010111 ^ 01010101 = 00000010
01011000 ^ 01011010 = 00000010
01011001 ^ 01011011 = 00000010
01011010 ^ 01011000 = 00000010
01011011 ^ 01011001 = 00000010
01011100 ^ 01011110 = 00000010
01011101 ^ 01011111 = 00000010
01011110 ^ 01011100 = 00000010
01011111 ^ 01011101 = 00000010
01100000 ^ 01100010 = 00000010
01100001 ^ 01100011 = 00000010
01100010 ^ 01100000 = 00000010
01100011 ^ 01100001 = 00000010
01100100 ^ 01100110 = 00000010
01100101 ^ 01100111 = 00000010
01100110 ^ 01100100 = 00000010
01100111 ^ 01100101 = 00000010
01101000 ^ 01101010 = 00000010
01101001 ^ 01101011 = 00000010
01101010 ^ 01101000 = 00000010
01101011 ^ 01101001 = 00000010
01101100 ^ 01101110 = 00000010
01101101 ^ 01101111 = 00000010
01101110 ^ 01101100 = 00000010
01101111 ^ 01101101 = 00000010
01110000 ^ 01110010 = 00000010
01110001 ^ 01110011 = 00000010
01110010 ^ 01110000 = 00000010
01110011 ^ 01110001 = 00000010
01110100 ^ 01110110 = 00000010
01110101 ^ 01110111 = 00000010
01110110 ^ 01110100 = 00000010
01110111 ^ 01110101 = 00000010
01111000 ^ 01111010 = 00000010
01111001 ^ 01111011 = 00000010
01111010 ^ 01111000 = 00000010
01111011 ^ 01111001 = 00000010
01111100 ^ 01111110 = 00000010
01111101 ^ 01111111 = 00000010
01111110 ^ 01111100 = 00000010
01111111 ^ 01111101 = 00000010
10000000 ^ 10000010 = 00000010
10000001 ^ 10000011 = 00000010
10000010 ^ 10000000 = 00000010
10000011 ^ 10000001 = 00000010
10000100 ^ 10000110 = 00000010
10000101 ^ 10000111 = 00000010
10000110 ^ 10000100 = 00000010
10000111 ^ 10000101 = 00000010
10001000 ^ 10001010 = 00000010
10001001 ^ 10001011 = 00000010
10001010 ^ 10001000 = 00000010
10001011 ^ 10001001 = 00000010
10001100 ^ 10001110 = 00000010
10001101 ^ 10001111 = 00000010
10001110 ^ 10001100 = 00000010
10001111 ^ 10001101 = 00000010
10010000 ^ 10010010 = 00000010
10010001 ^ 10010011 = 00000010
10010010 ^ 10010000 = 00000010
10010011 ^ 10010001 = 00000010
10010100 ^ 10010110 = 00000010
10010101 ^ 10010111 = 00000010
10010110 ^ 10010100 = 00000010
10010111 ^ 10010101 = 00000010
10011000 ^ 10011010 = 00000010
10011001 ^ 10011011 = 00000010
10011010 ^ 10011000 = 00000010
10011011 ^ 10011001 = 00000010
10011100 ^ 10011110 = 00000010
10011101 ^ 10011111 = 00000010
10011110 ^ 10011100 = 00000010
10011111 ^ 10011101 = 00000010
10100000 ^ 10100010 = 00000010
10100001 ^ 10100011 = 00000010
10100010 ^ 10100000 = 00000010
10100011 ^ 10100001 = 00000010
10100100 ^ 10100110 = 00000010
10100101 ^ 10100111 = 00000010
10100110 ^ 10100100 = 00000010
10100111 ^ 10100101 = 00000010
10101000 ^ 10101010 = 00000010
10101001 ^ 10101011 = 00000010
10101010 ^ 10101000 = 00000010
10101011 ^ 10101001 = 00000010
10101100 ^ 10101110 = 00000010
10101101 ^ 10101111 = 00000010
10101110 ^ 10101100 = 00000010
10101111 ^ 10101101 = 00000010
10110000 ^ 10110010 = 00000010
10110001 ^ 10110011 = 00000010
10110010 ^ 10110000 = 00000010
10110011 ^ 10110001 = 00000010
10110100 ^ 10110110 = 00000010
10110101 ^ 10110111 = 00000010
10110110 ^ 10110100 = 00000010
10110111 ^ 10110101 = 00000010
10111000 ^ 10111010 = 00000010
10111001 ^ 10111011 = 00000010
10111010 ^ 10111000 = 00000010
10111011 ^ 10111001 = 00000010
10111100 ^ 10111110 = 00000010
10111101 ^ 10111111 = 00000010
10111110 ^ 10111100 = 00000010
10111111 ^ 10111101 = 00000010
11000000 ^ 11000010 = 00000010
11000001 ^ 11000011 = 00000010
11000010 ^ 11000000 = 00000010
11000011 ^ 11000001 = 00000010
11000100 ^ 11000110 = 00000010
11000101 ^ 11000111 = 00000010
11000110 ^ 11000100 = 00000010
11000111 ^ 11000101 = 00000010
11001000 ^ 11001010 = 00000010
11001001 ^ 11001011 = 00000010
11001010 ^ 11001000 = 00000010
11001011 ^ 11001001 = 00000010
11001100 ^ 11001110 = 00000010
11001101 ^ 11001111 = 00000010
11001110 ^ 11001100 = 00000010
11001111 ^ 11001101 = 00000010
11010000 ^ 11010010 = 00000010
11010001 ^ 11010011 = 00000010
11010010 ^ 11010000 = 00000010
11010011 ^ 11010001 = 00000010
11010100 ^ 11010110 = 00000010
11010101 ^ 11010111 = 00000010
11010110 ^ 11010100 = 00000010
11010111 ^ 11010101 = 00000010
11011000 ^ 11011010 = 00000010
11011001 ^ 11011011 = 00000010
11011010 ^ 11011000 = 00000010
11011011 ^ 11011001 = 00000010
11011100 ^ 11011110 = 00000010
11011101 ^ 11011111 = 00000010
11011110 ^ 11011100 = 00000010
11011111 ^ 11011101 = 00000010
11100000 ^ 11100010 = 00000010
11100001 ^ 11100011 = 00000010
11100010 ^ 11100000 = 00000010
11100011 ^ 11100001 = 00000010
11100100 ^ 11100110 = 00000010
11100101 ^ 11100111 = 00000010
11100110 ^ 11100100 = 00000010
11100111 ^ 11100101 = 00000010
11101000 ^ 11101010 = 00000010
11101001 ^ 11101011 = 00000010
11101010 ^ 11101000 = 00000010
11101011 ^ 11101001 = 00000010
11101100 ^ 11101110 = 00000010
11101101 ^ 11101111 = 00000010
11101110 ^ 11101100 = 00000010
11101111 ^ 11101101 = 00000010
11110000 ^ 11110010 = 00000010
11110001 ^ 11110011 = 00000010
11110010 ^ 11110000 = 00000010
11110011 ^ 11110001 = 00000010
11110100 ^ 11110110 = 00000010
11110101 ^ 11110111 = 00000010
11110110 ^ 11110100 = 00000010
11110111 ^ 11110101 = 00000010
11111000 ^ 11111010 = 00000010
11111001 ^ 11111011 = 00000010
11111010 ^ 11111000 = 00000010
11111011 ^ 11111001 = 00000010
11111100 ^ 11111110 = 00000010
11111101 ^ 11111111 = 00000010
11111110 ^ 11111100 = 00000010
11111111 ^ 11111101 = 00000010
Dari hasil di atas dapat disimpulkan bahwa 1 ciphertext dapat dihasilkan dari banyak kemungkinan. Semakin panjang plaintext maka ciphertext juga semakin panjang sehingga jumlah kemungkinan juga akan meningkat. Itulah kenapa algoritme Vernam Cipher menjadi tidak mungkin atau sangat sulit untuk dipecahkan. Sangat sulit bahkan tidak mungkin untuk bisa mengetahui key yang sebenarnya karena tidak adanya karakteristik yang unik.
Tidak ada cara perhitungan matematika atau logika yang dapat digunakan untuk memecahkan algoritme Vernam Cipher. Hanya ada 1 cara untuk memecahkan algoritme Vernam Cipher yaitu dengan mengandalkan tebakan keberuntungan. Walaupun dikatakan tidak mungkin dipecahkan tetapi di dunia ini tidak ada yang tidak mungkin.