基本原理:
ECB模式加密将明文分成若干个等长的块(一般是128位,16个字节),然后对每个块单独使用相同的密钥进行加密。每个明文块都独立于其它块,并加密为相应的密文块。
这种加密方式简单,容易理解,但是安全性并不高。不能用于加密敏感数据。
这是最基础的加密方式,目前的加密方案可以在此基础上进行改进。
比如说:
CBC模式加密:可以通过将前一块密文与当前明文块进行异或,来进行加密。
CTR模式加密:使用一个计时器对每个块进行不同的加密,这可以保证即使明文块相同,但是密文块也依然不同。
ECB加密过程:
1.先将明文分割为多个块,每块长度与算法的块大小相同(比如AES的128位块)。
2.对每个明文块,使用同一个加密密钥进行独立加密,产生对应的密文块。
3.对所有密文块进行组合,生成最终的密文输出。
ECB解密过程
1.将收到的密文分割为多个块。
2.对每个密文块使用相同的密钥进行解密,得到对应的明文块。
3.组合所有的明文块,恢复出原始数据。
使用c++来实现:
#include <iostream>
#include <openssl/aes.h>
#include <cstring>
//填充函数
void Padding(unsigned char* input, int inputLen, int blockSize) {
int padLen = blockSize - (inputLen % blockSize);
for (int i = 0; i < padLen; i++) {
input[inputLen + i] = padLen;
}
}
//移除填充函数
void Unpadding(unsigned char* input, int* inputLen) {
int padLen = input[*inputLen - 1];
*inputLen -= padLen;
}
//主函数
int main() {
unsigned char key[AES_BLOCK_SIZE] = "abcdefghigklmno";//设置密钥
unsigned char plaintext[] = "Hello,world.";//设置原始明文
int plaintextLen = strlen((char*)plaintext);//计算原始明文长度
printf("明文:%s\n",plaintext);
//把明文长度填充到AES_BLOCK_SIZE的整数倍
int paddedLen = ((plaintextLen / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;
unsigned char paddedPlaintext[paddedLen];
memcpy(paddedPlaintext, plaintext, plaintextLen);
Padding(paddedPlaintext, plaintextLen, AES_BLOCK_SIZE);
//对加密的密文存储
unsigned char ciphertext[paddedLen];
//创建AES加密上下文
AES_KEY encryptKey;
AES_set_encrypt_key(key, 128, &encryptKey);
//使用密钥对每个块进行加密
for (int i = 0; i < paddedLen; i += AES_BLOCK_SIZE) {
AES_ecb_encrypt(paddedPlaintext + i, ciphertext + i, &encryptKey, AES_ENCRYPT);
}
//输出密文
std::cout << "密文: ";
for (int i = 0; i < paddedLen; ++i) {
printf("%02x", ciphertext[i]);//输出密文
}
std::cout << std::endl;
// 解密
unsigned char decryptedText[paddedLen];
AES_KEY decryptKey;
AES_set_decrypt_key(key, 128, &decryptKey);
//解密
for (int i = 0; i < paddedLen; i += AES_BLOCK_SIZE) {
AES_ecb_encrypt(ciphertext + i, decryptedText + i, &decryptKey, AES_DECRYPT);
}//对每个块进行解密
//移除填充
int decryptedLen = paddedLen;
Unpadding(decryptedText, &decryptedLen);
//输出解密后的明文
std::cout << "解密后的明文: ";
for (int i = 0; i < decryptedLen; ++i) {
std::cout << decryptedText[i];
}
std::cout << std::endl;
return 0;
}
在Ubuntu系统里面,使用g++进行编译:
g++ ecb.cpp -o ecb -lssl -lcrypto
最后输出结果如图: