Search code examples
pythonc++aes

decrypting cipher results in missing letters


I have a python endpoint that encrypts string using AES cbc mode and returns it to the client software written in c++ (in a hex space separated format ) The link for the c++ repo


std::vector<unsigned char> cipher_as_chars(std::string cipher) 
{
    std::istringstream strm{cipher};
    strm >> std::hex;
    std::vector<unsigned char> res;
    res.reserve(cipher.size() / 3 + 1);
    int h;
    while (strm >> h) {
        res.push_back(static_cast<unsigned char>(h));
    }
    return res;
}
namespace client{
    std::string decrypt_cipher(std::string cipher, std::string usr_key)
    {
        std::string original_text  = "";
        const std::vector<unsigned char> key = key_from_string(usr_key);      // 16-char = 128-bit

        const unsigned char iv[16] = {
            0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x49, 0x56, 0x34, 0x35, 0x36
        };
       
        std::vector<unsigned char> encrypted = cipher_as_chars(cipher);
        unsigned long padded_size = 0;
        std::vector<unsigned char> decrypted(encrypted.size());

        plusaes::decrypt_cbc(&encrypted[0], encrypted.size(), &key[0], key.size(), &iv, &decrypted[0], decrypted.size(), &padded_size);
        


        for (int i =0 ; i < decrypted.size(); i++)
        {
            //cout << decrypted[i] << endl;
            std::stringstream stream;
            stream << decrypted[i];
            original_text = original_text + stream.str();
        }

        return original_text;
    }
}

def encrypt_string(key,text):
    result = ''
    while len(text)% 16 != 0 :
        text = text+" "
    string_as_bytes = text.encode('utf8')
    
    obj = AES.new(key.encode("utf8"), AES.MODE_CBC, 'This is an IV456'.encode("utf8"))
    cipher_text = obj.encrypt(string_as_bytes)
    
    for item in bytearray(cipher_text):
        result += f"{hex(item).replace('0x','')} "
    return result

@api.route('/test')
def test_route():
    return encrypt_string("Encryptionkey123", "Happy new year people")


The server has an encryption and decryption function same with the client software if I encrypt a string using the c++ code and decrypt it using decryption function written in c++ it works fine and I get the same string, but when the client reads the response of /test and encrypts it and the c++ client tries to decrypt it outputs the string missing n letters in the end

The original text in python server Happy new year people

The output in the c++ client Happy new year p


Solution

  • Look at this example pycrypto does support pkcs#7 padding your take on padding is poor, just use the built-in padding function in that module

    Example taken from the link

    from Crypto.Cipher import AES
    from Crypto.Util.Padding import pad
    from Crypto.Util.Padding import unpad
    
    key=b'1234567890123456'
    cipher=AES.new(key,AES.MODE_CBC)
    
    text=b'secret text'
    padtext=pad(text,16,style='pkcs7')
    cipherText=cipher.encrypt(padtext)
    print(padtext)
    print(cipherText)
    
    plaintext=cipher.decrypt(cipherText)  #can't use same object to decrypt
    print(plaintext)
    

    you might want to add some code to turn the result into a hex separated string