对称加密是一种加密方法,其中加密和解密使用相同的密钥。这意味着发送方和接收方都必须拥有相同的密钥才能进行安全的通信。
-
常见的对称加密算法:
-
AES(高级加密标准):是目前最广泛使用的对称加密算法之一,支持128、192和256位密钥长度。
-
DES(数据加密标准):曾经广泛使用,但由于密钥长度较短(56位),现在已不再被认为是安全的。
-
3DES(三重数据加密算法):是DES的一个改进版本,使用三个不同的56位密钥对数据进行三次加密。
-
Blowfish:由Bruce Schneier设计,支持可变长度的密钥,从32位到448位。
-
Twofish:是Blowfish的后继者,也是可变长度的密钥,支持128、192和256位密钥长度。
-
IDEA(国际数据加密算法):是一种使用128位密钥的加密算法。
-
-
工作模式:
-
对称加密算法可以以不同的模式工作,以适应不同的安全需求,例如:
-
ECB(电子密码本模式):最简单的模式,但安全性较低。
-
CBC(密码块链模式):提高了安全性,但需要一个初始化向量(IV)。
-
CFB(密文反馈模式):允许加密算法以流模式操作。
-
OFB(输出反馈模式):类似于CFB,但使用不同的反馈机制。
-
CTR(计数器模式):将加密算法转换为流密码,提供很好的安全性。
-
-
流密码(Stream Cipher)是一种对称加密算法,它将明文分割成一个个的位或字节,然后使用一个密钥流(keystream)与明文逐位或逐字节进行运算(通常是异或操作),生成密文。流密码的主要特点是加密和解密过程是连续的,并且可以实时处理数据流。
流密码的特点:
-
实时性:流密码可以对数据流进行实时加密和解密,适合于需要即时处理的应用场景,如通信加密。
-
密钥流:流密码的核心是生成一个与明文等长的密钥流,这个密钥流是随机的,并且每次加密时都不同。
-
简单高效:流密码算法通常实现简单,计算效率高,适合于硬件和软件实现。
-
自同步:如果传输过程中出现错误,流密码可以自同步,即接收方可以继续解密后续的数据而不需要重新同步。
-
安全性:流密码的安全性依赖于密钥流的随机性和不可预测性。如果密钥流被预测或泄露,流密码的安全性就会受到威胁。
RC4加密算法就属于对称加密里的流密码中的一种
原理:
密钥调度算法(KSA):初始化一个256字节的数组S,并根据密钥进行置换,产生一个伪随机状态。
伪随机生成算法(PRGA):从S数组生成密钥流,通过不断交换数组元素和产生伪随机字节来生成密钥流。
加密/解密过程:将密钥流与明文进行异或,得到密文。解密时用相同的过程,将密文与密钥流进行异或恢复明文。
#include <stdio.h>
#include <string.h>
// RC4密钥调度算法 (KSA)
void RC4_KSA(const unsigned char *key, int key_len, unsigned char *S) {
int i, j = 0;
unsigned char temp;
// 初始化S数组
for (i = 0; i < 256; i++) {
S[i] = i;
}
// 密钥调度
for (i = 0; i < 256; i++) {
j = (j + S[i] + key[i % key_len]) % 256;
// 交换S[i]和S[j]
temp = S[i];
S[i] = S[j];
S[j] = temp;
}
}
// RC4伪随机生成算法 (PRGA)
void RC4_PRGA(unsigned char *S, unsigned char *data, int data_len) {
int i = 0, j = 0, k;
unsigned char temp;
unsigned char keystream;
for (k = 0; k < data_len; k++) {
i = (i + 1) % 256;
j = (j + S[i]) % 256;
// 交换S[i]和S[j]
temp = S[i];
S[i] = S[j];
S[j] = temp;
// 生成密钥流
keystream = S[(S[i] + S[j]) % 256];
// 将明文与密钥流异或,得到密文(加密或解密)
data[k] ^= keystream;
}
}
// RC4加密/解密
void RC4(unsigned char *key, int key_len, unsigned char *data, int data_len) {
unsigned char S[256];
RC4_KSA(key, key_len, S);
RC4_PRGA(S, data, data_len);
}
int main() {
// 密钥可以是任何长度的字节序列
unsigned char key[] = "mysecretkey";
int key_len = strlen((char *)key);
// 明文数据
unsigned char data[] = "Hello, RC4 Encryption!";
int data_len = strlen((char *)data);
// 输出原始明文
printf("Original data: %s\n", data);
// 加密
RC4(key, key_len, data, data_len);
printf("Encrypted data: ");
for (int i = 0; i < data_len; i++) {
printf("%02X", data[i]); // 打印密文(以十六进制输出)
}
printf("\n");
// 解密(与加密过程相同)
RC4(key, key_len, data, data_len);
printf("Decrypted data: %s\n", data); // 输出解密后的明文
return 0;
}
# RC4加密和解密脚本
def rc4(key, data):
"""
RC4 加密/解密函数
:param key: 密钥,字节序列
:param data: 要加密或解密的字节数据
:return: 加密/解密后的字节数据
"""
# 密钥调度算法(KSA)
S = list(range(256)) # 初始化S数组
j = 0
key_length = len(key)
for i in range(256):
j = (j + S[i] + key[i % key_length]) % 256
S[i], S[j] = S[j], S[i] # 交换S[i]和S[j]
# 伪随机生成算法(PRGA)
i = 0
j = 0
result = bytearray()
for byte in data:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i] # 交换S[i]和S[j]
K = S[(S[i] + S[j]) % 256] # 生成伪随机字节
result.append(byte ^ K) # 将明文字节与密钥流异或,得到密文字节
return bytes(result)
# 示例使用:
if __name__ == "__main__":
# 密钥可以是任何长度的字节序列(比如:b"mysecretkey")
key = b"mysecretkey"
# 明文数据
plaintext = b"Hello, RC4 Encryption!"
# 加密
encrypted = rc4(key, plaintext)
print(f"Encrypted: {encrypted}")
# 解密
decrypted = rc4(key, encrypted)
print(f"Decrypted: {decrypted.decode()}") # 输出解密后的明文