Data Encryption Standard (DES)
Friends don’t spy; true friendship is about privacy, too.
– Stephen King
Algoritma DES dikembangkan di IBM dibawah kepemimpinan W.L. Tuchman pada tahun 1972. Algoritma ini didasarkan pada algoritma Lucifer yang dibuat oleh Horst Feistel.
DES termasuk ke dalam sistem kriptografi simetri dan tergolong jenis cipher blok.
DES beroperasi pada ukuran blok 64 bit. DES mengenkripsikan 64 bit plainteks menjadi 64 bit cipherteks dengan menggunakan 56 bit kunci internal (internal key) atau upa-kunci (subkey). Kunci internal dibangkitkan dari kunci eksternal (external key) yang panjangnya 64 bit.
Implementasi dengan menggunakan Python:
ip = [58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7]
ip_inv = [40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25]
expansion = [32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1]
permutation_box = [16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25]
def d(lis):
return "".join(str(x) for x in lis)
def rotate_left(data, n):
return data[n:] + data[:n]
def str2bin(msg):
dummy = []
for i in range(len(msg)):
bits = bin(ord(msg[i]))[2:]
bits = '00000000'[len(bits):] + bits
dummy.extend([int(b) for b in bits])
return dummy
def key_builder(ext_key):
pc1 = [57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4]
pc2 = [14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32]
key_round = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1]
raw_result = []
final_key = []
for i in range(len(pc1)):
raw_result.append(ext_key[pc1[i] - 1])
left = raw_result[:28]
right = raw_result[28:]
for i in range(len(key_round)):
left = rotate_left(left, key_round[i])
right = rotate_left(right, key_round[i])
ki = left + right
aur = []
for j in range(len(pc2)):
aur.append(ki[pc2[j] - 1])
final_key.append(aur)
return final_key
def split_message(msg):
msg_split = []
j = 0
for i in range(0, len(msg), 64):
msg_split.append(msg[i:i + 64])
if len(msg_split[j]) < 64:
miss = 64 - len(msg_split[j])
padding = "".join(str(int(x * 0)) for x in range(miss))
msg_split[j].extend([int(b) for b in padding])
j += 1
return msg_split
def permutation_function(msg, table):
dummy = []
for i in range(len(table)):
dummy.append(msg[table[i] - 1])
return dummy
def xor_with_key(msg, key_f):
dummy = []
for i in range(len(msg)):
dummy.append(msg[i] ^ key_f[i])
return dummy
def s_box(msg):
s1 = [[14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, ],
[0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, ],
[4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, ],
[15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, ], ]
s2 = [[15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, ],
[3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, ],
[0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, ],
[13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, ], ]
s3 = [[10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, ],
[13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, ],
[13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, ],
[1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, ], ]
s4 = [[7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, ],
[13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, ],
[10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, ],
[3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, ], ]
s5 = [[2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, ],
[14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, ],
[4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, ],
[11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, ], ]
s6 = [[12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, ],
[10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, ],
[9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, ],
[4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, ], ]
s7 = [[4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, ],
[13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, ],
[1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, ],
[6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, ], ]
s8 = [[13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, ],
[1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, ],
[7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, ],
[2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11, ], ]
s = [s1, s2, s3, s4, s5, s6, s7, s8]
b = []
index = 0
for k in range(8):
ar = msg[index:index + 6]
index += 6
row = int(str(ar[0]) + str(ar[5]), 2)
column = int(''.join([str(x) for x in ar[1:5]]), 2)
value = bin(s[k][row][column])[2:]
value = '0000'[len(value):] + value
b.extend([int(x) for x in value])
return b
def encrypt(messages, internal_key):
messages = split_message(messages)
cipher = ""
for msg in messages:
permutation = permutation_function(msg, ip)
left, right = permutation[:32], permutation[32:]
for i in range(16):
expand = permutation_function(right, expansion)
vector_a = xor_with_key(expand, internal_key[i])
vector_b = s_box(vector_a)
pb = permutation_function(vector_b, permutation_box)
temp = right
right = []
for k in range(len(pb)):
right.append(pb[k] ^ left[k])
left = temp
raw = right + left
final = permutation_function(raw, ip_inv)
cipher += "".join(str(x) for x in final)
return cipher
def decrypt(messages, internal_key):
messages = split_message(messages)
plaintext = ""
for msg in messages:
permutation = permutation_function(msg, ip)
left, right = permutation[:32], permutation[32:]
for i in range(15, -1, -1):
expand = permutation_function(right, expansion)
vector_a = xor_with_key(expand, internal_key[i])
vector_b = s_box(vector_a)
pb = permutation_function(vector_b, permutation_box)
temp = right
right = []
for k in range(len(pb)):
right.append(pb[k] ^ left[k])
left = temp
raw = right + left
final = permutation_function(raw, ip_inv)
plaintext += "".join(str(x) for x in final)
return plaintext
# open key
externalKey = open('pass.txt', 'r').read()
key_in_binary = str2bin(externalKey)
key = key_builder(key_in_binary)
# message 8-byte (text)
# message = open('message.txt', 'r').read()
# message = str2bin(message)
# message in json (more than 8-byte)
message = open('example.json', 'r').read()
message = str2bin(message)
# encrypt message
ciphertext = encrypt(message, key)
print("Ciphertext =", ciphertext)
aa = []
aa.extend([int(x) for x in ciphertext])
# decrypt message
print("Plaintext =", d(message))
print("Plaintext =", decrypt(aa, key))