Python - Ciphertext length must be equal to key size - different string length after passing it to server
<p>I have a problem with decoding the encrypted message after passing it from client to the server. I am using <a href="https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/" rel="nofollow">Cryptography</a>. I am encoding the message on the client side using the script below:</p>

<pre><code>encMessage = public_key.encrypt(message, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(),label=None))
</code></pre>

<p>After this encoding the <em>len()</em> function on the client side tells me properly that the <em>encMessage</em> is 256 long. Also the <em>type()</em> function tells me that <em>encMessage</em> is <em>'str'</em>. The <em>encMessage</em> when printed looks something like this:</p>

<blockquote>
  <p>I\xf0gr\xf5\xf8\xf2F\xde\xc7\xe4\x91\xa1F3\xc1\x05\x06\xd7Y:\xc9\xcf\xed'\xf49\xd5\x99Z\xed\x93\xba8\xdd\x0b\xe3?</p>
</blockquote>

<p>However, when I pass this <em>encMessage</em> to the server using <em>rest_framework</em> then, after using the code below on the server side:</p>

<pre><code>message = private_key.decrypt(encMessage,padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(),label=None))
</code></pre>

<p>I get the error: "Ciphertext length must be equal to key size". I checked this and now the <em>len()</em> function on the server side used on <em>encMessage</em> gives me not 256 but something smaller. Also the <em>type()</em> function shows <em>'unicode'</em>.</p>

<p>I assume that there is something wrong with <em>encMessage</em> conversion during data sending from client to server but I have no idea what to do with it.</p>

<p>Thank you in advance for any suggestions!</p>

<p><strong>EDIT:</strong></p>

<p>Answering the comment about showing how I communicate with the server and send the data - this is what I do:</p>

<pre><code>data = {'message': $scope.message};
loginApi.getMessageEncrypted(data)
    .success(
        function(dataEncrypted) {
            loginApi.checkMessage(dataEncrypted['encMessage'])
                .success(
                    function(dataDecrypted) {
                        $log.log('Server responded properly');
                    })
                .error(
                    function(errorInfo, status) {
                        $log.info('Server user data answer error.')
                    });
        })
    .error(
        function(errorInfo, status) {
            $log.info('Client encryption error.')
        });
</code></pre>

<p>Explanation:</p>

<p>After clicking some button on the website angular's <em>getMessageEncrypted</em> function sends <em>message</em> in <em>data</em> variable using <em>post</em> to <em>django REST framework</em> APIview and then serializer object which are written in python on the client side. In serializer the message is encrypted using:</p>

<pre><code>encMessage = public_key.encrypt(message, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(),label=None))
dataEncrypted = {'encMessage': encMessage};
return dataEncrypted
</code></pre>

<p>and sent back to angular using <em>dataEncrypted</em> dictionary-like variable. Then this message is sent with angular's <em>checkMessage</em> function (also with <em>post</em>) to the <em>django REST framework</em> APIview and then serializer object on the server side. In server's serializer the message is decrypted using:</p>

<pre><code>message = private_key.decrypt(encMessage,padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(),label=None))
</code></pre>

<p>and similarly sent back to angular in <em>dataDecrypted</em> dictionary-like variable. However, this never happens because in the decryption line I get <em>Ciphertext length must be equal to key size</em> error.</p>

<p>I think that there is some change of the message coding (like utf-8, unicode or something) on the border of client-angular when encrypted message is sent to angular from python function on the client side or on the border of angular-server when encrypted message is sent from angular to python APIview on the server side.</p>

<p>I am really sorry for probably lack of "naming" experience. I am not really into proper nomenclature.</p>

<p><strong>SOLUTION</strong></p>

<p>User <a href="http://stackoverflow.com/users/1350899/mata">mata</a> answered my question. What I had to do was to encode encrypted message with <em>base64</em> before returning it to angular and sending it to server api. Then on the server side I had to decode it from <em>base64</em> and then decode the message. Thank you again!</p>

<p>Your encrypted message is a binary blob of data, and you seem to treat it as string in javascript, but javascript strings are not made for binary data, and when the transport format is json it gets even more complicated.</p>

<p>The standard approach would be to base64 encode the encrypted message before sending and decode it when it's received.</p>

python string cryptography