Search code examples
pythonjsonrsadecodeencode

How do I decode /encode signature in rsa in python


I am making a password manager and I have been having the same issue with rsa and json for a couple days

I need to write the signature in a json file but when I try to write the signature in the json file I get the following error

TypeError: Object of type bytes is not JSON serializable

Knowing that the error occurs because the signature is in a byte format I tried turning the bytes to a string. Unforunatly turning the signature to string causes the verification to fail

I tried to decode the bytes in order to save them to the json file and encoding them afterwards but doing this brings up a new error

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x9a in position 0: invalid start byte

I need to find the correct codeset in order to encode and decode

This is the code if there is a some type of a bug

# python
import json
import Rsakit

# code ...
Rsaencryption = RsaKit() # Rsaencrytpion is a custom module I wrote
Signature = Rsaencryption.RsaSign(Provided_password,PrivateKey) 
json_file_format['Method']['Rsa'] = {
                    "Public_Key":PublicKey.decode('ascii'),"Private_Key":PrivateKey.decode('ascii'),"Date":self.date,"Singature":Signature.decode('utf-8') # <--bug here
                    }

If the signature is left encoded I will get the first error If I try to decode the signature the second error will occur I have also tried to decode it with ascii and still nothing

Function RsaSign:

# python
def RsaSign(self, message:str, key): # Private key required
        """
        For key use the Private one
        """
        return rsa.sign(message.encode('ascii'), key, "SHA-1")

Json file:

// Json
{
    "Methods": {
        "Rsa": {
            "Public_Key": Public Key,
            "Private_Key": Private key,
            "Date": "02-08-2022",
            "Singature": "\\x82<F\\xbc\\x9b\\xe4by\\x83\\x021o\\x9b\\x11\\xc6\\x8d^\\xb6z'\\xbcgH\\x8c\\x1d\\xf60\\x017\\xd3\\x8b\\xc3\\x93\\xc52\\x8c\\xc1%\\xaa\\xc8\\xadW\\xdc\\x"
        }
    },
    "Config": {
        "ID": "29d256f5-1254-11ed-a5ac-84470900bff8",
        "Date": "02-08-2022"
    }
}

Solution

  • Your serialization abstraction should deal with converting your byte array to/from a string. I'd recommend hex encoding, see here. Essentially:

    # to hex str:
    b'\x01\x02\x03'.hex()
    
    # to bytes:
    bytes.fromhex('010203')
    

    That is, don't try to treat arbitrary bytes as though they were actual UTF-8 bytes. That'd be akin to treating them as if they were a .PNG image. They're not, they're arbitrary bytes!

    Then all of your encrypting/decrypting abstractions should just work with bytes.

    And, of course, the usual disclaimer - don't roll with your own encryption/decryption systems for anything serious. Go open source, use something tried and tested and built by people that are more familiar with all the little nuances that make something bulletproof, and completely undermine it.

    PS: Please check the spelling of Rsaencrytpion and Singature!