1
0

fix: fix mdbook content

This commit is contained in:
2025-10-15 16:32:50 +08:00
parent 7b34736618
commit 2beb0e8ce9
4 changed files with 12 additions and 130 deletions

View File

@@ -47,7 +47,7 @@ Base64是一种基于64个可打印字符来表示二进制数据个表示方法
Padding: = Padding: =
例如编码一个"Hello World"字符串: 例如使用ascii或等效兼容的utf8编码一个"Hello World"字符串:
H -> 01001000 H -> 01001000
e -> 01100101 e -> 01100101
@@ -69,7 +69,7 @@ d -> 01100100
此处对应最后一组不足6位因此填充两位0对齐至6位。 此处对应最后一组不足6位因此填充两位0对齐至6位。
并在最终的编码末尾添加一个=表示填充了两位0。 并在最终的编码末尾添加一个=表示填充了两位0。
对应的编码就是SGVsbG8gV29ybGQ= 对应的Base64编码就是SGVsbG8gV29ybGQ=
如果最后一组填充了四位0则最终编码末尾添加两个=。 如果最后一组填充了四位0则最终编码末尾添加两个=。

View File

@@ -24,7 +24,7 @@
- 读取包含多行十六进制字符串的文件 - 读取包含多行十六进制字符串的文件
- 将所有行连接成一个长字符串进行处理 - 将所有行连接成一个长字符串进行处理
### 3. 滑动窗口解密检测 ### 滑动窗口解密检测
**实现策略:** **实现策略:**

View File

@@ -24,22 +24,7 @@ ICE
4. **XOR运算**:对每对字节执行`a ^ b`操作 4. **XOR运算**:对每对字节执行`a ^ b`操作
5. **结果收集**将所有XOR结果收集为`Vec<u8>` 5. **结果收集**将所有XOR结果收集为`Vec<u8>`
### 3. 主函数实现 ### 主函数实现
```rust
fn main() -> Result<()> {
let plaintexts = r#"
Burning 'em, if you ain't quick and nimble I go crazy when I hear a cymbal
"#;
let key = b"ICE";
for plaintext in plaintexts.lines() {
let plaintext_bytes = plaintext.as_bytes();
let cipher = xor_with_key(plaintext_bytes, key)?;
println!("{}", hex::encode(cipher));
}
Ok(())
}
```
**执行流程:** **执行流程:**
@@ -63,5 +48,3 @@ Burning 'em, if you ain't quick and nimble I go crazy when I hear a cymbal
- **比单字节XOR更安全**:密钥长度增加了破解难度 - **比单字节XOR更安全**:密钥长度增加了破解难度
- **仍然脆弱**:存在重复模式,可通过频率分析攻击 - **仍然脆弱**:存在重复模式,可通过频率分析攻击
- **历史意义**Vigenère密码的电子版本 - **历史意义**Vigenère密码的电子版本
这种实现展示了如何使用Rust的迭代器和函数式编程特性来优雅地处理密码学算法。

View File

@@ -7,6 +7,7 @@
**数据文件:** `6.txt` **数据文件:** `6.txt`
该文件包含Base64编码的加密数据例如 该文件包含Base64编码的加密数据例如
``` ```
HUIfTQsPAh9PE048GmllH0kcDk4TAQsHThsBFkU2AB4BSWQgVB0dQzNTTmVS HUIfTQsPAh9PE048GmllH0kcDk4TAQsHThsBFkU2AB4BSWQgVB0dQzNTTmVS
BgBHVBwNRU0HBAxTEjwMHghJGgkRTxRMIRpHKwAFHUdZEQQJAGQmB1MANxYG BgBHVBwNRU0HBAxTEjwMHghJGgkRTxRMIRpHKwAFHUdZEQQJAGQmB1MANxYG
@@ -16,83 +17,18 @@ DBoXQR0BUlQwXwAgEwoFR08SSAhFTmU+Fgk4RQYFCBpGB08fWXh+amI2DB0P
**原始数据来源:** [https://cryptopals.com/static/challenge-data/6.txt](https://cryptopals.com/static/challenge-data/6.txt) **原始数据来源:** [https://cryptopals.com/static/challenge-data/6.txt](https://cryptopals.com/static/challenge-data/6.txt)
## 代码实现与解析 ## 原理简介
### 1. 依赖引入 ### Hamming距离原理
```rust
use core::f32;
use std::fs;
use std::{cmp::Ordering, str::from_utf8};
use std::collections::HashMap;
use anyhow::{Result, anyhow};
use base64::{Engine, engine::general_purpose::STANDARD};
use common::xor_with_key;
```
### 2. Base64解码函数
```rust
fn base64_to_bytes(input: &str) -> Result<Vec<u8>> {
Ok(STANDARD.decode(input)?)
}
```
### 3. Hamming距离计算
```rust
fn hamming_distance(input_1: &[u8], input_2: &[u8]) -> Result<u32> {
if input_1.len() != input_2.len() {
return Err(anyhow!("Can't count hamming distance"));
}
let hamming_distance = input_1
.iter()
.zip(input_2.iter())
.map(|(a, b)| (a ^ b).count_ones())
.sum::<u32>();
Ok(hamming_distance)
}
```
**Hamming距离原理**
- 计算两个等长字节序列的位差异数量 - 计算两个等长字节序列的位差异数量
- 使用XOR运算找出不同的位 - 使用XOR运算找出不同的位
- `count_ones()`统计结果中1的个数 - `count_ones()`统计结果中1的个数
### 4. 密钥长度推测 ### 密钥长度推测
```rust
fn get_posible_keysize(cipher_bytes: &[u8]) -> Result<usize> {
let mut posible_keysizes: HashMap<usize, f32> = HashMap::new();
for keysize in 2..=40 {
if cipher_bytes.len() < 4 * keysize {
return Err(anyhow!("Wrong keysize"));
}
let mut total_distance = 0;
for i in 0..=(cipher_bytes.len() - 4 * keysize) {
let slice_1 = &cipher_bytes[i..i + keysize];
let slice_2 = &cipher_bytes[i + keysize..i + 2 * keysize];
let slice_3 = &cipher_bytes[i + 2 * keysize..i + 3 * keysize];
let slice_4 = &cipher_bytes[i + 3 * keysize..i + 4 * keysize];
total_distance += hamming_distance(slice_1, slice_2)?;
total_distance += hamming_distance(slice_1, slice_3)?;
total_distance += hamming_distance(slice_1, slice_4)?;
total_distance += hamming_distance(slice_2, slice_3)?;
total_distance += hamming_distance(slice_2, slice_4)?;
total_distance += hamming_distance(slice_3, slice_4)?;
}
let score = total_distance as f32 / keysize as f32;
posible_keysizes.insert(keysize, score);
}
let mut posible_keysizes: Vec<_> = posible_keysizes.into_iter().collect();
posible_keysizes.sort_by(|a, b| a.1.partial_cmp(&b.1).unwrap_or(Ordering::Equal));
Ok(posible_keysizes.first().unwrap().0)
}
```
**密钥长度推测策略:** **密钥长度推测策略:**
1. **多块采样**取连续的4个密钥长度大小的块 1. **多块采样**取连续的4个密钥长度大小的块
2. **距离计算**计算所有块之间的Hamming距离 2. **距离计算**计算所有块之间的Hamming距离
3. **归一化评分**:除以密钥长度进行归一化 3. **归一化评分**:除以密钥长度进行归一化
@@ -127,51 +63,13 @@ fn score_english_text(input: &[u8]) -> f32 {
``` ```
**频率分析原理:** **频率分析原理:**
- 使用英文字母的标准频率分布 - 使用英文字母的标准频率分布
- 计算文本与标准频率的匹配程度 - 计算文本与标准频率的匹配程度
- 分数越高,越可能是有效英文文本 - 分数越高,越可能是有效英文文本
### 6. 主破解流程
```rust
fn main() -> Result<()> {
let cipher = fs::read_to_string("./problems/p6/6.txt")?;
let cipher: String = cipher.lines().collect();
let cipher_bytes = base64_to_bytes(&cipher)?;
let posible_keysize = get_posible_keysize(&cipher_bytes)?;
// 按密钥长度分组
let mut blocks: Vec<Vec<u8>> = vec![Vec::new(); posible_keysize];
for (i, &byte) in cipher_bytes.iter().enumerate() {
blocks[i % posible_keysize].push(byte);
}
let mut key_list: Vec<u8> = Vec::new();
for block in blocks {
let mut high_score = 0_f32;
let mut possible_key = 0_u8;
for key in 0..=255 {
let decrypted: Vec<u8> = block.iter().map(|&b| b ^ key).collect();
let score = score_english_text(&decrypted);
if score > high_score {
high_score = score;
possible_key = key;
}
}
key_list.push(possible_key);
}
let str_key = String::from_utf8(key_list.clone())?;
println!("key: {str_key}");
let plaintext = xor_with_key(&cipher_bytes, &key_list)?;
let str_plaintext = from_utf8(&plaintext)?;
println!("plaintext: {str_plaintext}");
Ok(())
}
```
**破解步骤:** **破解步骤:**
1. **读取密文**从Base64文件读取加密数据 1. **读取密文**从Base64文件读取加密数据
2. **推测密钥长度**使用Hamming距离分析 2. **推测密钥长度**使用Hamming距离分析
3. **分组密文**:按密钥长度将密文分组 3. **分组密文**:按密钥长度将密文分组
@@ -181,6 +79,7 @@ fn main() -> Result<()> {
## 密码分析原理 ## 密码分析原理
这个挑战展示了经典的Vigenère密码分析技术 这个挑战展示了经典的Vigenère密码分析技术
- **Hamming距离**:利用重复密钥的周期性特征 - **Hamming距离**:利用重复密钥的周期性特征
- **频率分析**:基于英文字母的统计分布 - **频率分析**:基于英文字母的统计分布
- **分组技术**将复杂问题分解为多个单字节XOR问题 - **分组技术**将复杂问题分解为多个单字节XOR问题