Reputation: 83
I have a problem with decoding the encrypted message after passing it from client to the server. I am using Cryptography. I am encoding the message on the client side using the script below:
encMessage = public_key.encrypt(message, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(),label=None))
After this encoding the len() function on the client side tells me properly that the encMessage is 256 long. Also the type() function tells me that encMessage is 'str'. The encMessage when printed looks something like this:
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?
However, when I pass this encMessage to the server using rest_framework then, after using the code below on the server side:
message = private_key.decrypt(encMessage,padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(),label=None))
I get the error: "Ciphertext length must be equal to key size". I checked this and now the len() function on the server side used on encMessage gives me not 256 but something smaller. Also the type() function shows 'unicode'.
I assume that there is something wrong with encMessage conversion during data sending from client to server but I have no idea what to do with it.
Thank you in advance for any suggestions!
EDIT:
Answering the comment about showing how I communicate with the server and send the data - this is what I do:
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.')
});
Explanation:
After clicking some button on the website angular's getMessageEncrypted function sends message in data variable using post to django REST framework APIview and then serializer object which are written in python on the client side. In serializer the message is encrypted using:
encMessage = public_key.encrypt(message, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(),label=None))
dataEncrypted = {'encMessage': encMessage};
return dataEncrypted
and sent back to angular using dataEncrypted dictionary-like variable. Then this message is sent with angular's checkMessage function (also with post) to the django REST framework APIview and then serializer object on the server side. In server's serializer the message is decrypted using:
message = private_key.decrypt(encMessage,padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(),label=None))
and similarly sent back to angular in dataDecrypted dictionary-like variable. However, this never happens because in the decryption line I get Ciphertext length must be equal to key size error.
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.
I am really sorry for probably lack of "naming" experience. I am not really into proper nomenclature.
SOLUTION
User mata answered my question. What I had to do was to encode encrypted message with base64 before returning it to angular and sending it to server api. Then on the server side I had to decode it from base64 and then decode the message. Thank you again!
Upvotes: 5
Views: 8712
Reputation: 1
User mata(1st answer) works for me too. I spoiled one whole day for this. In python import base64
On receiving end
import base64
rec_data = base64.b64decode(received_data)
Upvotes: 0
Reputation: 349
I got the same error when working with encryption on django project. In order to solve the error check bellow points
Upvotes: 0
Reputation: 69082
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.
The standard approach would be to base64 encode the encrypted message before sending and decode it when it's received.
Upvotes: 4