浅谈密码相关原理及代码实现
字数 1665 2025-08-22 12:22:43
密码学原理及代码实现详解
一、古典密码学
1. 凯撒密码 (Caesar Cipher)
原理:将字母按字母表顺序移动指定偏移量(如3),非字母字符保持不变。
代码实现:
string caesarEncrypt(string text, int shift) {
string result = "";
for (char c : text) {
if (isalpha(c)) {
char base = islower(c) ? 'a' : 'A';
result += (c - base + shift) % 26 + base;
} else {
result += c; // 非字母不加密
}
}
return result;
}
特点:
- 偏移量可调整,用于创建不同的密钥
- 解密时只需反向移动同样偏移量
- 安全性较低,易被频率分析破解
2. 维吉尼亚密码 (Vigenère Cipher)
原理:使用关键字中每个字母的偏移量加密文本,根据字母表循环使用关键字。
代码实现:
string vigenereEncrypt(string text, string key) {
string result = "";
int keyIndex = 0;
for (char c : text) {
if (isalpha(c)) {
char base = islower(c) ? 'a' : 'A';
int shift = key[keyIndex % key.size()] - base;
result += (c - base + shift) % 26 + base;
keyIndex++;
} else {
result += c;
}
}
return result;
}
特点:
- 每个字母偏移量由关键字决定,增加加密强度
- 比凯撒密码更安全,但仍可能被破解
- 密钥长度影响安全性
3. 栅栏密码 (Rail Fence Cipher)
原理:将文本分布在多个行(栅栏)中,按上下顺序排列字符,最后按行拼接。
代码实现:
string railFenceEncrypt(string text, int key) {
vector<string> rail(key, "");
int direction = 1; // 1向下,-1向上
int row = 0;
for (char c : text) {
rail[row] += c;
row += direction;
if (row == 0 || row == key - 1) direction = -direction;
}
string result = "";
for (string line : rail) result += line;
return result;
}
特点:
- 属于换位密码的一种
- 安全性较低,易被识别
- 栅栏行数越多越复杂
4. 单表替代密码 (Simple Substitution Cipher)
原理:为每个字母定义唯一的替换字母,使用替代表逐字替换。
代码实现:
string substitutionEncrypt(string text, unordered_map<char, char> substitutionTable) {
string result = "";
for (char c : text) {
if (isalpha(c)) {
result += substitutionTable[c];
} else {
result += c;
}
}
return result;
}
特点:
- 比凯撒密码更安全
- 仍可能被频率分析破解
- 密钥空间大(26!种可能)
5. Playfair密码
原理:构造5x5字母矩阵,按规则将字母对替换为矩阵中的对应字母。
代码实现:
vector<vector<char>> createPlayfairMatrix(string key) {
vector<vector<char>> matrix(5, vector<char>(5));
string alphabet = "ABCDEFGHIKLMNOPQRSTUVWXYZ"; // 'J'合并到'I'
string adjustedKey = "";
vector<bool> used(26, false);
// 处理密钥
for (char c : key) {
if (c == 'J') c = 'I';
if (!used[c - 'A'] && isalpha(c)) {
adjustedKey += c;
used[c - 'A'] = true;
}
}
// 填充剩余字母
for (char c : alphabet) {
if (!used[c - 'A']) {
adjustedKey += c;
used[c - 'A'] = true;
}
}
// 填充矩阵
int k = 0;
for (int i = 0; i < 5; ++i)
for (int j = 0; j < 5; ++j)
matrix[i][j] = adjustedKey[k++];
return matrix;
}
string encryptPair(char a, char b, const vector<vector<char>>& matrix) {
int row1, col1, row2, col2;
// 查找字母位置
for (int i = 0; i < 5; ++i) {
for (int j = 0; j < 5; ++j) {
if (matrix[i][j] == a) row1 = i, col1 = j;
if (matrix[i][j] == b) row2 = i, col2 = j;
}
}
// 加密规则
if (row1 == row2) { // 同行
return string(1, matrix[row1][(col1 + 1) % 5]) + matrix[row2][(col2 + 1) % 5];
} else if (col1 == col2) { // 同列
return string(1, matrix[(row1 + 1) % 5][col1]) + matrix[(row2 + 1) % 5][col2];
} else { // 矩形
return string(1, matrix[row1][col2]) + matrix[row2][col1];
}
}
特点:
- 比单字母替换更安全
- 需要处理字母对
- 对短消息安全性较好
6. 希尔密码 (Hill Cipher)
原理:使用矩阵乘法对字母对进行加密,每对字母转换为向量与密钥矩阵相乘。
代码实现:
vector<vector<int>> keyMatrix = {{6, 24}, {1, 13}};
string hillEncrypt(string text) {
string result = "";
for (int i = 0; i < text.size(); i += 2) {
int x = text[i] - 'A';
int y = text[i + 1] - 'A';
result += (keyMatrix[0][0] * x + keyMatrix[0][1] * y) % 26 + 'A';
result += (keyMatrix[1][0] * x + keyMatrix[1][1] * y) % 26 + 'A';
}
return result;
}
特点:
- 基于线性代数
- 需要可逆矩阵
- 对已知明文攻击脆弱
二、现代密码学
1. AES (Advanced Encryption Standard)
原理:
- 块加密:使用固定大小的块(128位)
- 密钥长度:支持128、192和256位
- 多轮替代和排列:S盒替代、行移位、列混合、轮密钥添加
代码实现:
string aesEncrypt(const string& text, const unsigned char* key) {
AES_KEY encryptKey;
AES_set_encrypt_key(key, 128, &encryptKey);
unsigned char encrypted[AES_BLOCK_SIZE];
AES_encrypt((unsigned char*)text.c_str(), encrypted, &encryptKey);
return string((char*)encrypted, AES_BLOCK_SIZE);
}
特点:
- 对称密钥加密
- 安全性强,广泛使用
- 需要安全交换密钥
2. RSA加密
原理:
- 非对称加密:公钥加密,私钥解密
- 基于大整数分解难题
- 用于密钥交换、数字签名
代码实现:
string rsaEncrypt(const string& text, const string& publicKeyFile) {
FILE* pubKeyFile = fopen(publicKeyFile.c_str(), "r");
RSA* rsa = PEM_read_RSA_PUBKEY(pubKeyFile, NULL, NULL, NULL);
fclose(pubKeyFile);
unsigned char encrypted[256];
int encryptedLen = RSA_public_encrypt(text.size(),
(unsigned char*)text.c_str(),
encrypted,
rsa,
RSA_PKCS1_PADDING);
RSA_free(rsa);
return string((char*)encrypted, encryptedLen);
}
特点:
- 安全性高
- 计算开销大
- 广泛用于HTTPS和VPN
3. SHA-256哈希函数
原理:
- 单向函数:无法从结果反推输入
- 固定输出长度:256位
- 用于数据完整性校验
代码实现:
string sha256(const string& text) {
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256((unsigned char*)text.c_str(), text.size(), hash);
char outputBuffer[65];
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
sprintf(outputBuffer + (i * 2), "%02x", hash[i]);
}
outputBuffer[64] = 0;
return string(outputBuffer);
}
特点:
- 抗碰撞性强
- 用于数字签名
- 不可逆
4. HMAC (Hash-based Message Authentication Code)
原理:
- 哈希函数结合密钥
- 确保数据完整性和来源认证
- 用于TLS和JWT等协议
代码实现:
string hmacSha256(const string& text, const string& key) {
unsigned char* result;
unsigned int len = 32;
result = HMAC(EVP_sha256(),
key.c_str(),
key.size(),
(unsigned char*)text.c_str(),
text.size(),
NULL,
NULL);
char outputBuffer[65];
for (int i = 0; i < len; i++) {
sprintf(outputBuffer + (i * 2), "%02x", result[i]);
}
outputBuffer[64] = 0;
return string(outputBuffer);
}
特点:
- 防篡改
- 验证消息真实性
- 常用于API认证
三、创新加密方法
1. 双重加密
原理:对相同明文进行两次AES加密,使用两个不同密钥。
代码实现:
void AES_encrypt(const vector<unsigned char>& input,
vector<unsigned char>& output,
const vector<unsigned char>& key) {
AES_KEY encryptKey;
AES_set_encrypt_key(key.data(), 128, &encryptKey);
AES_encrypt(input.data(), output.data(), &encryptKey);
}
// 主函数中使用两次加密
vector<unsigned char> key1(AES_BLOCK_SIZE);
vector<unsigned char> key2(AES_BLOCK_SIZE);
RAND_bytes(key1.data(), key1.size());
RAND_bytes(key2.data(), key2.size());
vector<unsigned char> input(AES_BLOCK_SIZE, 'A');
vector<unsigned char> output1(AES_BLOCK_SIZE), output2(AES_BLOCK_SIZE);
AES_encrypt(input, output1, key1); // 第一次加密
AES_encrypt(output1, output2, key2); // 第二次加密
特点:
- 增加安全性
- 需要管理多个密钥
- 计算开销增加
2. 中英文字符映射加密
原理:定义英文字母与中文汉字的映射表,进行查表替换。
代码实现:
unordered_map<char, string> englishToChinese = {
{'a', "阿"}, {'b', "博"}, {'c', "成"}, // 更多映射...
{'A', "安"}, {'B', "北"}, {'C', "川"} // 大写字母映射
};
string encryptToChinese(const string& input) {
string encryptedText = "";
for (char c : input) {
if (englishToChinese.find(c) != englishToChinese.end()) {
encryptedText += englishToChinese[c];
} else {
encryptedText += c;
}
}
return encryptedText;
}
// 解密函数需要反向映射表
string decryptToEnglish(const string& input) {
unordered_map<string, char> chineseToEnglish;
for (const auto& pair : englishToChinese) {
chineseToEnglish[pair.second] = pair.first;
}
string decryptedText = "";
string buffer;
for (char c : input) {
if ((unsigned char)c >= 0x80) { // 判断是否为汉字
buffer += c;
if (buffer.size() == 3) { // 汉字通常是3字节
if (chineseToEnglish.find(buffer) != chineseToEnglish.end()) {
decryptedText += chineseToEnglish[buffer];
} else {
decryptedText += buffer;
}
buffer.clear();
}
} else {
decryptedText += c;
}
}
return decryptedText;
}
特点:
- 简单易实现
- 安全性较低
- 适合简单加密需求
3. 双角色交互加密
原理:A和B各有专属密钥,消息经过双重加密和双重解密流程。
流程:
- A用A密钥加密 → B
- B用B密钥加密 → A
- A用A密钥解密 → B
- B用B密钥解密得到原文
代码实现:
// A和B各自有专属密钥
unordered_map<char, string> AKey = {
{'h', "海"}, {'e', "恩"}, {'l', "兰"}, {'o', "欧"}, // 更多映射...
};
unordered_map<char, string> BKey = {
{'h', "鸿"}, {'e', "艺"}, {'l', "雷"}, {'o', "欧"}, // 更多映射...
};
// 角色A的通信流程
string message = "helloworld";
string encryptedByA = encrypt(message, AKey); // A加密
sendToB(encryptedByA);
// 角色B收到后
string receivedFromA = receiveFromA();
string encryptedByB = encrypt(receivedFromA, BKey); // B加密
sendToA(encryptedByB);
// 角色A收到后
string receivedFromB = receiveFromB();
string decryptedByA = decrypt(receivedFromB, AKey); // A解密
sendToB(decryptedByA);
// 角色B最后解密
string finalReceived = receiveFromA();
string finalMessage = decrypt(finalReceived, BKey); // B解密得到原文
特点:
- 增加中间人攻击难度
- 需要安全通道交换密钥
- 双重保护机制
四、密码学应用总结
- 机密性:防止未经授权的信息访问(AES, RSA)
- 完整性:确保数据未被篡改(SHA-256, HMAC)
- 认证:验证通信双方身份(数字证书, HMAC)
- 不可否认性:防止发送方否认发送行为(数字签名)
五、未来发展方向
- 后量子密码学:抵抗量子计算攻击的新算法
- 同态加密:支持在加密数据上直接计算
- 多方安全计算:保护隐私的协同计算
- 区块链技术:密码学在分布式系统中的应用
密码学作为信息安全的基石,将持续为数字社会提供安全保障,其创新和发展将直接影响网络安全的前景。