成员:李泽坤、吴科明
我们首先展示用户界面和输入输出不合法的情况。
当输入的信息和密钥内容或者位数不合法时,会重新输入(图2,图3):
接下来,我们展示级别的加加解密操作:
输入明文:01101101
我们得到了下面的加密结果:
接下来,我们用刚才得到的密文和密钥进行解密:
密文:10010000
密钥:1101100111
解密结果为:01101101
这和我们最开始使用的明文是一致的,至此我们结束了第一关的测试
本次测试使用内容如下:
明文1:11001100
密钥1:0101011010
明文2:rng
密钥2:0101011010
我们程序的ASCII码明文加密测试:
交叉测试组的两个加密结果:
密文为: ['00010000']
密文为: i�\
可以看出,我们和其他小组的交叉测试结果是一样的, 交叉测试通过!
我们的作品进行了拓展,加密算法的数据输入可以是ASII编码字符串(分组为1 Byte)
对应地输出也可以是ACII字符串(很可能是乱码)。而且我们使用的是web开发,在网页显示中,还纯在部分乱码是不可见的,不可以复制的状态
下图是加密演示:
明文:Hello
密钥:1010000010
密文:ä\��«
面是对应的解密演示:
解密成功,得到对应的明文,演示结束,第三关通过。
在第4关中,我们尝试使用暴力破解的方法来找到正确的密钥。
对于一份已知的明文密文文对,我们得到了多份密钥的解,并使用单线程与多线程的方式对比破解效率。
在软件界面上选择对应的破解功能:
首先,我们展示单密文对破解功能:
输入明文、密文对。
轻松得到破解结果。
然后,我们展示多密文对破解功能:
输入多组明密文对,注意以英文分号隔开。
第四关测试通过。
在第四关中,我们使用了
明文:10111001
密文:01110011
得到了4个正确密钥: ['1001100011', '1010101101', '1101100011', '1110101101']
所以,一个明文"10111001"与密文"01110011"存在4个可能的密钥:'1001100011', '1010101101', '1101100011', 和 '1110101101'。这说明对于这个特定的明密文对,确实存在不止一个密钥Key。
下面解释问题二:
同时,如上图,我们使用明文:10111001,密钥1001100011和1010101101,都得到了密文01110011。
对于明文空间内任意给定的明文分组,确实存在可能性,即选择不同的密钥,加密可以得到相同的密文。
本系统采用c/s架构来实现S-DES加解密算法。它支持普通的加解密,ASCII码的加解密,以及暴力破解功能。
- Logo容器: 显示系统相关的logo。
- 标题: 显示系统的主标题。
- 选项列表: 用户可以选择二进制、ASCII或暴力破解。
- 输入部分: 允许用户输入信息和密钥。
- 信息容器: 显示开发单位和开发者信息。
- 背景: 页面背景采用图片,能够自动调整大小以适应不同的屏幕。
- 提示: 提供清晰的界面和按钮提示用户进行输入。
- 交互: 选项列表允许用户选择操作类型。选择暴力破解后,系统将跳转到另一页面。
- 界面1的设计: 下面是本系统的初始界面的html文件。选择暴力破解后,系统将跳转到另一页面。
<!DOCTYPE html>
<html>
<head>
<style>
body {
background-image: url("/static/lan_F.jpg");
background-size: cover;
color: white;
height: 50vh;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
margin: 0;
font-size: 3em;
font-family: Arial, sans-serif;
}
.logo-container {
position: absolute;
top: 10px;
left: 10px;
display: flex;
align-items: center;
}
.logo-container img {
height: 50px;
margin-right: 10px;
}
.title {
font-size: 1em;
margin-bottom:50px;
margin-top:200px;
}
.select-container {
margin: 20px 0; /* 上下边距为20px, 左右边距为0 */
font-size: 40px; /* 字体大小为16px */
display: flex; /* 使用flex布局以使label和select在同一行 */
align-items: center; /* 垂直居中对齐内容 */
}
.select-container label {
margin-right: 10px; /* 在label和select之间增加10px的间距 */
}
.select-container select {
padding: 5px 10px; /* 选择框内部的填充:上下5px,左右10px */
border: 1px solid #cccccc; /* 给选择框一个灰色的边框 */
border-radius: 4px; /* 边框圆角为4px */
}
.profile-container img {
width: 100%;
height: auto;
}
/* New CSS for login form */
/* 应该是灰框*/
.login-container {
display: flex;
flex-direction: column;
background: rgba(0, 0, 0, 0.5); /* semi-transparent background */
padding: 10px; /* reduce padding */
border-radius: 5px;
font-size: 0.5em;
padding: 20px; /* 增加内边距 */
width: 600px; /* 增加宽度 */
height: auto; /* 根据内容自适应高度 */
}
/* 这个是输入字体控制 */
.login-container input {
margin-bottom: 5px; /* reduce margin */
padding: 5px; /* reduce padding */
font-size: 0.8em; /* reduce font-size */
background: transparent; /* make input box transparent */
color: white; /* change text color to white */
border: none; /* remove input box border */
}
/* 这个是按钮控制 */
.login-container button {
padding: 5px;
background-color: lightblue;
color: black;
border: none;
cursor: pointer;
font-size: 0.5em; /* reduce font-size */
margin-bottom:30px;
}
/* New CSS for website information */
/* 这个是底部字体 */
.info-container {
position: absolute;
bottom: 0;
width: 100%;
text-align: center;
padding: 10px 0;
background-color: rgba(0, 0, 0, 0.5); /* semi-transparent background */
font-size: 0.2em; /* adjust font size */
}
</style>
<script>
window.onload = function() {
document.getElementById('login-button').onclick = function() {
var username = document.getElementById('username-input').value;
var password = document.getElementById('password-input').value;
var option = document.getElementById('option-list').value; // 获取当前选择的选项
fetch('/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({username: username, password: password, operation: "encryption", option: option})
}).then(response => response.json())
.then(data => alert(data.message));
}
// 添加事件监听器检测选择的变化
document.getElementById('option-list').addEventListener('change', function() {
if (this.value === "brute_force") {
window.location.href = "/brute_force_page"; // 假设新的HTML页面的路由为"/brute_force_page"
}
});
document.getElementById('login-button2').onclick = function() {
var username = document.getElementById('username-input').value;
var password = document.getElementById('password-input').value;
var option = document.getElementById('option-list').value; // 获取当前选择的选项
fetch('/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({username: username, password: password, operation: "decryption", option: option})
}).then(response => response.json())
.then(data => alert(data.message));
}
}
</script>
</head>
<body>
<div class="logo-container">
<img src="/static/logo1.png" alt="Logo 1">
<img src="/static/logo3.png" alt="Logo 3">
</div>
<div class="title">
S-DES加解密系统
</div>
<!-- 选项列表部分 -->
<div class="select-container">
<label for="option-list">选项:</label>
<select id="option-list">
<option value="binary">二进制</option>
<option value="asciil">ASCLL</option>
<option value="brute_force">暴力破解</option>
</select>
</div>
<!-- 文本部分 -->
<div class="login-container">
<input id="username-input" type="text" placeholder="信息" required/>
<!-- <input id="password-input" type="password" placeholder="密钥" required/>-->
<input id="password-input" type="text" placeholder="密钥(10bits)" required/>
<button id="login-button">加密</button>
<button id="login-button2">解密</button>
</div>
<!-- New website information -->
<div class="info-container">
<p>所属单位:重庆大学大数据与软件学院 | 分工小组:RNG</p>
<p>开发人员:吴科明 李泽坤 | 联系方式:[email protected]</p>
</div>
</body>
</html>
- 界面2的设计: 选择暴力破解后,系统将跳转到另一页面。下面是该页面的html文件。
<!DOCTYPE html>
<html>
<head>
<style>
body {
background-image: url("/static/lan_F.jpg");
background-size: cover;
color: white;
height: 50vh;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
margin: 0;
font-size: 3em;
font-family: Arial, sans-serif;
}
.logo-container {
position: absolute;
top: 10px;
left: 10px;
display: flex;
align-items: center;
}
.logo-container img {
height: 50px;
margin-right: 10px;
}
.title {
font-size: 1em;
margin-bottom:50px;
margin-top:200px;
}
.select-container {
margin: 20px 0; /* 上下边距为20px, 左右边距为0 */
font-size: 40px; /* 字体大小为16px */
display: flex; /* 使用flex布局以使label和select在同一行 */
align-items: center; /* 垂直居中对齐内容 */
}
.select-container label {
margin-right: 10px; /* 在label和select之间增加10px的间距 */
}
.select-container select {
padding: 5px 10px; /* 选择框内部的填充:上下5px,左右10px */
border: 1px solid #cccccc; /* 给选择框一个灰色的边框 */
border-radius: 4px; /* 边框圆角为4px */
}
.profile-container img {
width: 100%;
height: auto;
}
/* New CSS for login form */
/* 应该是灰框*/
.login-container {
display: flex;
flex-direction: column;
background: rgba(0, 0, 0, 0.5); /* semi-transparent background */
padding: 10px; /* reduce padding */
border-radius: 5px;
font-size: 0.5em;
padding: 20px; /* 增加内边距 */
width: 600px; /* 增加宽度 */
height: auto; /* 根据内容自适应高度 */
}
/* 这个是输入字体控制 */
.login-container input {
margin-bottom: 5px; /* reduce margin */
padding: 5px; /* reduce padding */
font-size: 0.8em; /* reduce font-size */
background: transparent; /* make input box transparent */
color: white; /* change text color to white */
border: none; /* remove input box border */
}
/* 这个是按钮控制 */
.login-container button {
padding: 5px;
background-color: lightblue;
color: black;
border: none;
cursor: pointer;
font-size: 0.5em; /* reduce font-size */
margin-bottom:30px;
}
/* New CSS for website information */
/* 这个是底部字体 */
.info-container {
position: absolute;
bottom: 0;
width: 100%;
text-align: center;
padding: 10px 0;
background-color: rgba(0, 0, 0, 0.5); /* semi-transparent background */
font-size: 0.2em; /* adjust font size */
}
</style>
<script>
window.onload = function() {
document.getElementById('login-button').onclick = function() {
var username = document.getElementById('username-input').value;
var password = document.getElementById('password-input').value;
fetch('/brute_force', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({username: username, password: password})
}).then(response => response.json())
.then(data => alert(data.message));
}
}
</script>
</head>
<body>
<div class="logo-container">
<img src="/static/logo1.png" alt="Logo 1">
<img src="/static/logo3.png" alt="Logo 3">
</div>
<div class="title">
S-DES加解密暴力破解系统
</div>
<!-- 文本部分 -->
<div class="login-container">
<input id="username-input" type="text" placeholder="明文" required/>
<!-- <input id="password-input" type="password" placeholder="密钥" required/>-->
<input id="password-input" type="text" placeholder="密文" required/>
<button id="login-button">开始破解</button>
</div>
<!-- New website information -->
<div class="info-container">
<p>所属单位:重庆大学大数据与软件学院 | 分工小组:RNG</p>
<p>开发人员:吴科明 李泽坤 | 联系方式:[email protected]</p>
</div>
</body>
</html>
-
permute(input_str, permutation_table)
: -
根据给定的置换表来进行置换。
def permute(input_str, permutation_table):
output_str = ''
for bit_position in permutation_table:
output_str += input_str[bit_position - 1]
return output_str
left_shift(key, n)
: 将输入字符串的左半部分和右半部分分别左移n
位。
def left_shift(key, n):
left_half = key[:5]
right_half = key[5:]
shifted_left = left_half[n:] + left_half[:n]
shifted_right = right_half[n:] + right_half[:n]
return shifted_left + shifted_right
generate_subkeys(key, p10_table, p8_table)
: 根据给定的P10和P8表生成子密钥。
def generate_subkeys(key, p10_table, p8_table):
p10_key = permute(key, p10_table)
key1 = permute(left_shift(p10_key, 1), p8_table)
key2 = permute(left_shift(left_shift(p10_key, 1), 1), p8_table)
return key1, key2
f_function(right_half, subkey, sbox0, sbox1, p4_table)
: 进行S-DES的F函数操作。
def f_function(right_half, subkey, sbox0, sbox1, p4_table):
# Expansion and XOR
expanded = permute(right_half, EXPANSION_PERMUTATION)
xored = int(expanded, 2) ^ int(subkey, 2)
xored_str = format(xored, '08b')
# S-box substitutions
s0_input = xored_str[:4]
s1_input = xored_str[4:]
s0_row = int(s0_input[0] + s0_input[3], 2)
s0_col = int(s0_input[1:3], 2)
s1_row = int(s1_input[0] + s1_input[3], 2)
s1_col = int(s1_input[1:3], 2)
s0_output = format(sbox0[s0_row][s0_col], '02b')
s1_output = format(sbox1[s1_row][s1_col], '02b')
s_output = s0_output + s1_output
# Permutation
return permute(s_output, p4_table)
ascii_to_binary(ascii_string)
: 将ASCII字符串转换为二进制。
def ascii_to_binary(ascii_string):
binary_string = ""
for character in ascii_string:
binary_string += bin(ord(character))[2:].zfill(8)
return binary_string
binary_to_ascii(binary_string)
: 将二进制转换为ASCII字符串。
def binary_to_ascii(binary_string):
ascii_string = ""
for i in range(0, len(binary_string), 8):
ascii_string += chr(int(binary_string[i:i + 8], 2))
return ascii_string
encrypt(plaintext, key)
: 使用给定的密钥对明文进行S-DES加密。
def encrypt(plaintext, key):
key1, key2 = generate_subkeys(key, PERMUTATION_P10, PERMUTATION_P8)
plaintext = permute(plaintext, INITIAL_PERMUTATION)
left_half = plaintext[:4]
right_half = plaintext[4:]
left_previous = right_half
f_result = f_function(right_half, key1, SBOX0, SBOX1, PERMUTATION_P4)
right_half1_int = int(left_half, 2) ^ int(f_result, 2)
right_half1 = format(right_half1_int, '04b')
f_result = f_function(right_half1, key2, SBOX0, SBOX1, PERMUTATION_P4)
right_half2_int = int(left_previous, 2) ^ int(f_result, 2)
right_half2 = format(right_half2_int, '04b')
return permute(right_half2 + right_half1, INVERSE_INITIAL_PERMUTATION)
decrypt(ciphertext, key)
: 使用给定的密钥对密文进行S-DES解密。
def decrypt(ciphertext, key):
key1, key2 = generate_subkeys(key, PERMUTATION_P10, PERMUTATION_P8)
ciphertext = permute(ciphertext, INITIAL_PERMUTATION)
right_previous = ciphertext[:4]
left_previous = ciphertext[4:]
f_result = f_function(left_previous, key2, SBOX0, SBOX1, PERMUTATION_P4)
left_half1_int = int(right_previous, 2) ^ int(f_result, 2)
left_half1 = format(left_half1_int, '04b')
f_result = f_function(left_half1, key1, SBOX0, SBOX1, PERMUTATION_P4)
right_half1_int = int(left_previous, 2) ^ int(f_result, 2)
right_half1 = format(right_half1_int, '04b')
return permute(right_half1 + left_half1, INVERSE_INITIAL_PERMUTATION)
encrypt_string(ascii_string, key)
: 对ASCII字符串进行加密。
def encrypt_string(ascii_string, key):
binary_string = ascii_to_binary(ascii_string)
encrypted_string = ""
for i in range(0, len(binary_string), 8):
plaintext = binary_string[i:i + 8]
ciphertext = encrypt(plaintext, key)
encrypted_string += ciphertext
return encrypted_string
decrypt_string(encrypted_string, key)
: 对已加密的字符串进行解密。
def decrypt_string(encrypted_string, key):
decrypted_string = ""
for i in range(0, len(encrypted_string), 8):
ciphertext = encrypted_string[i:i + 8]
plaintext = decrypt(ciphertext, key)
decrypted_string += plaintext
return decrypted_string
BruteForceDecrypt
类: 提供了单线程和多线程的暴力破解方法。
_brute_force(self, plaintext, ciphertext, start, end)
: 单线程暴力破解方法,从start到end范围内尝试所有的密钥。
class BruteForceDecrypt:
def __init__(self):
self.correct_keys = []
self.lock = threading.Lock()
def _brute_force(self, plaintext, ciphertext, start, end):
for key in range(start, end):
key_str = '{0:010b}'.format(key)
decrypted = decrypt(ciphertext, key_str)
if decrypted == plaintext and len(key_str) == 10:
with self.lock:
self.correct_keys.append(key_str)
def single_thread_brute_force(self, plaintext, ciphertext):
self._brute_force(plaintext, ciphertext, 0, 2 ** 10)
return self.correct_keys
def multi_thread_brute_force(self, plaintext, ciphertext):
threads = []
for i in range(8):
start = i * (2 ** 9)
end = (i + 1) * (2 ** 9)
thread = threading.Thread(target=self._brute_force, args=(plaintext, ciphertext, start, end))
thread.start()
threads.append(thread)
for thread in threads:
thread.join()
return self.correct_keys
def decrypt(self, plaintext, ciphertext):
start_time = time.time()
single_result = self.single_thread_brute_force(plaintext, ciphertext)
single_time = time.time() - start_time
self.correct_keys.clear()
start_time = time.time()
multi_result = self.multi_thread_brute_force(plaintext, ciphertext)
multi_time = time.time() - start_time
return {
"single_thread": {
"keys": single_result,
"time": single_time
},
"multi_thread": {
"keys": multi_result,
"time": multi_time
}
}
multi_thread_brute_force(self, plaintext, ciphertext)
: 多线程暴力破解接口,使用8个线程进行破解。
def multi_thread_brute_force(plaintext, ciphertext):
threads = []
for i in range(8):
start = i * (2 ** 9)
end = (i + 1) * (2 ** 9)
thread = threading.Thread(target=brute_force, args=(plaintext, ciphertext, start, end))
thread.start()
threads.append(thread)
# 等待所有线程完成
for thread in threads:
thread.join()
S-DES(Simplified Data Encryption Standard)是一个供教学而非安全使用的加密算法。它与DES的特性和结构类似,但参数小,明文分组为8位,主密钥分组为10位,采用两轮迭代。
S-DES加密过程包含两个重要部分:子密码生成过程和f函数结构。
子密码生成过程:
- 对初始密钥进行P10置换,将置换后的结果分为左右两部分,各5位。
- 对左右两部分进行循环左移操作和P8置换,得到K1。
- 再次对上一步结果进行循环左移操作和P8置换,得到K2。
f函数结构:
- 对右半部分进行E/P扩展置换,将其扩展为8位。
- 对扩展后的结果与轮密钥进行异或运算,再将异或的结果拆分成2个4位的块。
- 将这2个块分别通过S盒代替(S0和S1),然后再进行P4置换,最后将P4置换后的结果与左半部分进行异或,得到F函数输出的结果。
- 打开S-DES加解密系统主页。
- 选择所需的操作类型:二进制、ASCII或暴力破解。
- 输入信息和10位的密钥。如果输入不合法会报错。
- 点击“加密”或“解密”按钮以进行相应操作。
- 若选择了暴力破解,则系统会尝试所有可能的密钥,直到找到正确的密钥为止。这个过程可能需要一些时间,具体取决于你的计算机性能和你选择的明文和密文对的数量,并在完成后查看找到的正确密钥。
- 如果你选择了ASCII模式,那么你输入的信息应该是一个ASCII编码的字符串,而输出也将是一个ASCII编码的字符串。请注意,由于S-DES算法会对数据进行各种复杂的变换,所以加密后得到的字符串可能包含一些无法打印或无法显示的字符(即所谓的"乱码")。但这并不影响解密过程。只要知道正确的密钥,就可以使用S-DES算法将这个"乱码"字符串解密回原始字符串。
若有任何疑问或建议,请联系开发团队:[email protected]
我们的系统支持浏览器在线使用,如果你有需求,请你联系开发团队开启服务器。