2

我有以下代码可以加密和解密消息。

QString AesUtils::encrypt(QString message, QString aesKey)
{
    string plain = message.toStdString();
    qDebug() << "Encrypt" << plain.data() << " " << plain.size();
    string ciphertext;
    // Hex decode symmetric key:
    HexDecoder decoder;
    string stdAesKey = aesKey.toStdString();
    decoder.Put((byte*)stdAesKey.data(), aesKey.size());
    decoder.MessageEnd();
    word64 size = decoder.MaxRetrievable();
    char *decodedKey = new char[size];
    decoder.Get((byte *)decodedKey, size);
    // Generate Cipher, Key, and CBC
    byte key[ AES::MAX_KEYLENGTH ], iv[ AES::BLOCKSIZE ];
    StringSource( reinterpret_cast<const char *>(decodedKey), true,
                  new HashFilter(*(new SHA256), new ArraySink(key, AES::MAX_KEYLENGTH)) );
    memset( iv, 0x00, AES::BLOCKSIZE );
    CBC_Mode<AES>::Encryption Encryptor( key, sizeof(key), iv );
    StringSource( plain, true, new StreamTransformationFilter( Encryptor,
                  new HexEncoder(new StringSink( ciphertext )) ) );
    return QString::fromStdString(ciphertext);
}

QString AesUtils::decrypt(QString message, QString aesKey)
{
    string plain;
    string encrypted = message.toStdString();

    // Hex decode symmetric key:
    HexDecoder decoder;
    string stdAesKey = aesKey.toStdString();
    decoder.Put( (byte *)stdAesKey.data(), aesKey.size() );
    decoder.MessageEnd();
    word64 size = decoder.MaxRetrievable();
    char *decodedKey = new char[size];
    decoder.Get((byte *)decodedKey, size);
    // Generate Cipher, Key, and CBC
    byte key[ AES::MAX_KEYLENGTH ], iv[ AES::BLOCKSIZE ];
    StringSource( reinterpret_cast<const char *>(decodedKey), true,
                  new HashFilter(*(new SHA256), new ArraySink(key, AES::MAX_KEYLENGTH)) );
    memset( iv, 0x00, AES::BLOCKSIZE );
    try {
        CBC_Mode<AES>::Decryption Decryptor
        ( key, sizeof(key), iv );
        StringSource( encrypted, true,
                      new HexDecoder(new StreamTransformationFilter( Decryptor,
                                     new StringSink( plain )) ) );
    }
    catch (Exception &e) { // ...
        qDebug() << "Exception while decrypting " << e.GetWhat().data();
    }
    catch (...) { // ...
    }
        qDebug() << "decrypt" << plain.data() << " " << AES::BLOCKSIZE;
    return QString::fromStdString(plain);
}

问题是我随机得到:

StreamTransformationFilter: invalid PKCS #7 block padding found

解密内容时。加密应该完全支持QString,因为它可能包含一些 Unicode 数据。但即使使用仅包含 [Az][az][0-9] 的基本字符串,它也不起作用

aesKey大小为 256 。

在 Stack Overflow 上的一些答案之后,有人建议使用HexDecoder/ HexEncoder,但它并不能解决我的问题。

4

1 回答 1

0

我的代码的第一个问题是我在 aesKey QString 中输入了普通字符串。

因此,您需要提供十六进制格式的密钥,而不是“1231fsdf$5r4”:[0-9][AF]

然后,问题就在这里:

char *decodedKey = new char[size];
decoder.Get((byte *)decodedKey, size);

我猜这个字符串是完整的 64 个字节,最后没有 NULL 的空间。我改成以下问题后问题就消失了:

char *decodedKey = new char[size+2];

现在代码工作正常。希望这对将来的人有所帮助。

于 2016-01-18T21:08:30.480 回答