DES算法目前已经被破解。3DES是做了三次DES加密,虽然安全性能高了,但是加密解密效率降低了。
3DES分组大小为8字节,密钥总长度24字节,密钥1、密钥2、密钥3长度为8字节。
使用3DES的好处是加密和解密使用的是同一套算法,可以只编写一个接口就能完成加解密。
对称加密算法有5中加密模式,分别是ecb(最后一个分块需要填充)、cbc(需要填充)、ctr、cfb、ofb;
OpenSSL中的接口
//指明要用的算法和模式 const EVP_CIPHER *EVP_des_ede3_cbc(); //加解密的上下文 EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); //加解密初始化 //参数1上下文;参数2使用的算法;参数3密钥;参数4初始化向量;参数5加密为1,解密为0 int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv, int enc); //加密或者解密,这个接口只处理8字节整的数据,多出来的不处理 int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); //处理结尾不满8字节的数据 int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); //释放资源 void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *c);
以下案例实现文件加密和解密
#include<iostream> #include<openssl/evp.h> #include<openssl/err.h> #include<fstream> using namespace std; //参数1 密钥;参数2 输入文件;参数3 输出文件;参数4 ture表示加密 false表示解密 bool encrypto(string pwd, string file_in, string file_out, bool is_encryto) { //选择3des算法的cbc模式,可以修改算法 auto cipher = EVP_des_ede3_cbc(); int in_file_size = 0; //读的字节数 int out_file_size = 0;//写的字节数 ifstream ifs(file_in, ios::binary); if (!ifs) return false; ofstream ofs(file_out, ios::binary); if (!ofs) { ifs.close(); return false; } //创建上下文环境 auto ctx = EVP_CIPHER_CTX_new(); //密钥初始化 多的丢 unsigned char key[128] = { 0 }; //3des的密钥长度 int key_size = EVP_CIPHER_key_length(cipher); if (key_size > pwd.size()) { key_size = pwd.size(); } memcpy(key, pwd.c_str(), key_size); //初始化向量 unsigned char iv[128] = { 0 }; //加解密上下文环境 int ret = EVP_CipherInit(ctx, cipher, key, iv, is_encryto); if (!ret) { ERR_print_errors_fp(stderr); ifs.close(); ofs.close(); EVP_CIPHER_CTX_free(ctx); return false; } unsigned char buf[1024] = { 0 }; unsigned char out[1024] = { 0 }; int out_size = 0; //读文件 while (!ifs.eof()) { ifs.read((char *)buf, sizeof(buf)); int readn = ifs.gcount(); if (readn <= 0) break; in_file_size += readn; //读文件大小 //加密或者解密 EVP_CipherUpdate(ctx, out, &out_size, buf, readn); ofs.write((char *)out, out_size); out_file_size += out_size; } //处理最后一块,默认是以PKCS7方式打补丁 int last_size = 0; EVP_CipherFinal(ctx, out, &last_size); if (last_size > 0) { ofs.write((char *)out, last_size); out_file_size += last_size; } ifs.close(); ofs.close(); cout << "in_file_size:" << in_file_size << endl; cout << "out_file_size:" << out_file_size << endl; EVP_CIPHER_CTX_free(ctx); } int main() { encrypto("ae1234dsjhf", "plaintext.txt", "cipher.txt", true); encrypto("ae1234dsjhf", "cipher.txt", "mingwen.txt", false); }