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);
/////加解密初始化
/////param ctx:上下文
/////param cipher:使用的算法
/////param key:密钥
/////param iv:初始化向量
/////param enc:加密为1,解密为0
int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv, int enc); //加密或者解密,这个接口只处理8字节整的数据,多出来的不处理
/////param ctx:上下文
/////param out:输出
/////param outl:输出大小
/////param in:输入

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);  
}