//参考 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;
}