openssl實現des cbc加密


//參考 https://www.cnblogs.com/azbane/p/10179660.html
QByteArray ZYB::Openssl::DES_CBC(const QByteArray &keyStr, const QByteArray &data, ZYB::Openssl::Type type)
{
    DES_cblock keyEncrypt;
    memset(keyEncrypt, 0, 8);
    memcpy(keyEncrypt, keyStr.constData(), static_cast<size_t>(keyStr.length()));

    DES_key_schedule keySchedule;//密鑰表
    DES_set_key_unchecked(&keyEncrypt, &keySchedule);//設置密鑰,且不檢測密鑰奇偶性

    //IV設置爲0x0000000000000000
    DES_cblock ivec;
    memset(ivec, 0, sizeof(ivec));

    int len = 0;
    unsigned char* output = nullptr;

    switch (type) {
    case Encrypt: {
        len = (data.length()+7)/8 * 8;
        output = new unsigned char[len+1];
        memset(output, '\0', static_cast<size_t>(len+1) );
        DES_ncbc_encrypt(reinterpret_cast<const uchar *>(data.data()),
                         output,
                         data.length(),
                         &keySchedule, &ivec, DES_ENCRYPT);
        break;
    }
    case Decrypt: {
        len = data.length();
        output = new unsigned char[len+1];
        memset(output, '\0', static_cast<size_t>(len+1) );
        DES_ncbc_encrypt(reinterpret_cast<const uchar *>(data.data()),
                         output,
                         data.length() + 1,
                         &keySchedule, &ivec, DES_DECRYPT);
        break;
    }
    }

    QByteArray array;
    for(int i=0; i<len; ++i)
        array.append(static_cast<char>( output[i] ) );

    delete []output;

    return array;
}

//與DES_CBC結果一致

QByteArray ZYB::Openssl::DES_CBC_zeros(const QByteArray &key, const QByteArray &data, ZYB::Openssl::Type type)
{
    DES_cblock keyEncrypt;
    memset(keyEncrypt, 0, 8);
    memcpy(keyEncrypt, key.constData(), static_cast<size_t>(key.length()));

    DES_key_schedule keySchedule;//密鑰表
    DES_set_key_unchecked(&keyEncrypt, &keySchedule);//設置密鑰,且不檢測密鑰奇偶性

    //IV設置爲0x0000000000000000
    DES_cblock ivec;
    memset(ivec, 0, sizeof(ivec));


    const_DES_cblock inputText;
    DES_cblock outputText;

    QByteArray array;

    switch (type) {
    case Encrypt: {
        for(int i=0; i<data.length()/8; ++i) {
            memcpy(inputText, data.constData() + i * 8, 8);
            DES_ncbc_encrypt(inputText, outputText, 8, &keySchedule, &ivec, DES_ENCRYPT);  //加密

            for (int j = 0; j < 8; ++j) {
                array.append( static_cast<char>(outputText[j]) );
            }
            //重置ivec
            memcpy(ivec, outputText, 8);
        }
        if(data.length() % 8 != 0) {
            int tmp1 = data.length() / 8 * 8;
            int tmp2 = data.length() - tmp1;

            memset(inputText, 0, 8);
            memcpy(inputText, data.constData() + tmp1, static_cast<size_t>(tmp2) );
            DES_ncbc_encrypt(inputText, outputText, 8, &keySchedule, &ivec, DES_ENCRYPT);  //加密
            for (int j = 0; j < 8; ++j) {
                array.append( static_cast<char>(outputText[j]) );
            }
        }
        break;
    }
    case Decrypt: {
        for(int i=0; i<data.length()/8; ++i) {
            memcpy(inputText, data.constData() + i * 8, 8);
            DES_ncbc_encrypt(inputText, outputText, 8, &keySchedule, &ivec, DES_DECRYPT);  //加密

            for (int j = 0; j < 8; ++j) {
                array.append( static_cast<char>(outputText[j]) );
            }
            //重置ivec //解密過程不需要用前一塊的結果作爲下一塊的IV
            //memcpy(ivec, outputText, 8);
        }
        if(data.length() % 8 != 0) {
            int tmp1 = data.length() / 8 * 8;
            int tmp2 = data.length() - tmp1;

            memset(inputText, 0, static_cast<size_t>(tmp2));
            memcpy(inputText, data.constData() + tmp1, static_cast<size_t>(tmp2) );
            DES_ncbc_encrypt(inputText, outputText, tmp2, &keySchedule, &ivec, DES_DECRYPT);  //加密
            for (int j = 0; j < 8; ++j) {
                array.append( static_cast<char>(outputText[j]) );
            }
        }
        break;
    }
    }

    return array;
}

QByteArray ZYB::Openssl::DES_CBC_pkcs5(const QByteArray &key, const QByteArray &data, ZYB::Openssl::Type type)
{
    DES_cblock keyEncrypt;
    memset(keyEncrypt, 0, 8);
    memcpy(keyEncrypt, key.constData(), static_cast<size_t>(key.length()));

    DES_key_schedule keySchedule;//密鑰表
    DES_set_key_unchecked(&keyEncrypt, &keySchedule);//設置密鑰,且不檢測密鑰奇偶性

    //IV設置爲0x0000000000000000
    DES_cblock ivec;
    memset(ivec, 0, sizeof(ivec));


    const_DES_cblock inputText;
    DES_cblock outputText;

    QByteArray array;

    switch (type) {
    case Encrypt: {
        for(int i=0; i<data.length()/8; ++i) {
            memcpy(inputText, data.constData() + i * 8, 8);
            DES_ncbc_encrypt(inputText, outputText, 8, &keySchedule, &ivec, DES_ENCRYPT);  //加密

            for (int j = 0; j < 8; ++j) {
                array.append( static_cast<char>(outputText[j]) );
            }
            //重置ivec
            memcpy(ivec, outputText, 8);
        }
        if(data.length() % 8 != 0) {
            int tmp1 = data.length() / 8 * 8;
            int tmp2 = data.length() - tmp1;

            memset(inputText, (8-tmp2), 8);
            memcpy(inputText, data.constData() + tmp1, static_cast<size_t>(tmp2) );
        }
        else {
            memset(inputText, 8, 8);
        }
        DES_ncbc_encrypt(inputText, outputText, 8, &keySchedule, &ivec, DES_ENCRYPT);  //加密
        for (int j = 0; j < 8; ++j) {
            array.append( static_cast<char>(outputText[j]) );
        }
        break;
    }
    case Decrypt: {
        for(int i=0; i<data.length()/8; ++i) {
            memcpy(inputText, data.constData() + i * 8, 8);
            DES_ncbc_encrypt(inputText, outputText, 8, &keySchedule, &ivec, DES_DECRYPT);  //加密

            for (int j = 0; j < 8; ++j) {
                array.append( static_cast<char>(outputText[j]) );
            }
            //重置ivec //解密過程不需要用前一塊的結果作爲下一塊的IV
            //memcpy(ivec, outputText, 8);
        }
        if(data.length() % 8 != 0) {
            int tmp1 = data.length() / 8 * 8;
            int tmp2 = data.length() - tmp1;

            memset(inputText, 0, static_cast<size_t>(tmp2));
            memcpy(inputText, data.constData() + tmp1, static_cast<size_t>(tmp2) );
            DES_ncbc_encrypt(inputText, outputText, tmp2, &keySchedule, &ivec, DES_DECRYPT);  //加密
            for (int j = 0; j < 8; ++j) {
                array.append( static_cast<char>(outputText[j]) );
            }
        }
        break;
    }
    }

    return array;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章