StreamTransformationFilter:密文长度不是块大小的倍数

StreamTransformationFilter: ciphertext length is not a multiple of block size?

本文关键字:密文 StreamTransformationFilter      更新时间:2023-10-16

我正在尝试使用加密++中存在的aes算法加密和解密纯文本

这是我的加密方法

/*
 * Encrypt the given text
 */
template<typename T>
T encryptText(T plainText) {
    /* Key and IV setup
     * AES encryption uses a secret key of a variable length (128-bit, 196-bit or 256-   
     * bit). This key is secretly exchanged between two parties before communication   
     * begins. DEFAULT_KEYLENGTH= 16 bytes
     */
    byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ], iv[ CryptoPP::AES::BLOCKSIZE ];
    memset( key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH );
    memset( iv, 0x00, CryptoPP::AES::BLOCKSIZE );
    T cipherText;
    cout << "nnPlain Text size is (" << plainText.size() << " bytes)" << "nn";
    cout << plainText << "nn";
    /*
     * Create Cipher Text
     */
    CryptoPP::AES::Encryption aesEncryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH);
    CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, iv );
    CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink( cipherText ) );
    stfEncryptor.Put( reinterpret_cast<const unsigned char*>( plainText.c_str() ), plainText.length() + 1 );
    stfEncryptor.MessageEnd();
    cout << "nnCipher Text size is (" << cipherText.size() << " bytes)" << std::endl;
    for( int i = 0; i < cipherText.size(); i++ ) {
        cout << "0x" << std::hex << (0xFF & static_cast<byte>(cipherText[i])) << " ";
    }
    return cipherText;
}

这是我的解密方法

/*
 * Decrypt the given text
 */
template<typename T>
T decryptText(T encryptedText) {
    /* Key and IV setup
     * AES encryption uses a secret key of a variable length (128-bit, 196-bit or 256-   
     * bit). This key is secretly exchanged between two parties before communication   
     * begins. DEFAULT_KEYLENGTH= 16 bytes
     */
    byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ], iv[ CryptoPP::AES::BLOCKSIZE ];
    memset( key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH );
    memset( iv, 0x00, CryptoPP::AES::BLOCKSIZE );
    CryptoPP::AES::Decryption aesDecryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH);
    CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, iv );
    T decryptedText;
    CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink( decryptedText ) );
    stfDecryptor.Put( reinterpret_cast<const unsigned char*>( encryptedText.c_str() ), encryptedText.size() );
    stfDecryptor.MessageEnd();
    std::cout << "nnDecrypted Text is " << "nn";
    std::cout << "nn" << decryptedText << "nn";
    return decryptedText;
}

encryptText函数正常执行,我将它的输出保存在 mysql 数据库中。调用 decryptText 函数时发生错误,指出

An uncaught exception occurred: StreamTransformationFilter: ciphertext length is not a multiple of block size

而且我知道此错误是因为加密文本也可能包含一些 null(0( 值。如何解密实际文本。

编辑:

当我要求在评论部分显示我的sql查询时。

这是我的sql查询,用于获取mysql数据库中保存的加密数据。

template<typename T1, typename T2>
void getUserSms(T1 userId,vector<T1>& smsIds,vector<T2>& text){
    try{
        mysql::connection db_cs(config_cs_db());
        auto sms = db_cs.run(select(all_of(us)).from(us).where(us.usersUserId == userId));
        while(!sms.empty()){
            const auto& row = sms.front();
            auto smsId = row.id.value();
            smsIds.push_back(smsId);
            auto encryptedText = row.text.value();
            auto plainText = decryptText(encryptedText);
            text.push_back(plainText);
            sms.pop_front();
        }
        return;
    }
    catch (const sqlpp::exception& e) {
        std::cerr << "Could not get user sms due to some reason ...!!n";
        std:cerr << e.what() << "n";
        return;
    }
}

我正在使用sqlpp11进行sql查询。表格描述是

CREATE TABLE `user_sms`(
`id` BIGINT(50) NOT NULL AUTO_INCREMENT,
`sender_number` VARCHAR(20),
`text` VARCHAR(2000),
`incoming_time` TIMESTAMP,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`users_user_id` BIGINT(30),
PRIMARY KEY(`id`),
FOREIGN KEY(`users_user_id`) REFERENCES `users`(`user_id`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
  • 更改数组key和"iv from 字节to无符号字符"的数据类型
  • 将数据库表user_sms mysql中的text类型从 VARCHAR 更改为 BLOB

CREATE TABLE `user_sms`( // Changes below is the changes has been made. `text` BLOB, )ENGINE=InnoDB DEFAULT CHARSET=utf8;

感谢 jww 的帮助。