import base64 from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import padding from config import Config config = Config() def signUTF8( contentToSign : str, formatAutomatically : bool = True, addNewLine : bool = True, useNewKey : bool = False, twelveclient: bool = False ) -> str | bytes: """ Signs the content given ( Expected UTF8 ) and returns the signature but if formatAutomatically is set to True, it will return it in the proper format that the Roblox Client expects --rbxsig%signature% then the content addNewLine will add a new line to the start of the content before signing useNewKey will use RSA_PRIVATE_KEY_PATH2 instead of RSA_PRIVATE_KEY_PATH which is a 2048 bit key instead of 1024 :param contentToSign: The content to sign :param formatAutomatically: Whether to format the signature automatically :param addNewLine: Whether to add a new line to the start of the content before signing :param useNewKey: Whether to use RSA_PRIVATE_KEY_PATH2 instead of RSA_PRIVATE_KEY_PATH :returns: str | bytes (Signature or Formatted Signature) """ if addNewLine: contentToSign = "\n" + contentToSign contentToSign : bytes = contentToSign.encode( "utf-8" ) with open( config.RSA_PRIVATE_KEY_PATH if not useNewKey else config.RSA_PRIVATE_KEY_PATH2 , "rb" ) as f: private_key = serialization.load_pem_private_key( f.read(), password=None, backend=default_backend() ) signature = private_key.sign( contentToSign, padding.PKCS1v15(), hashes.SHA1() ) if formatAutomatically: if twelveclient: return "%{}%{}".format( base64.b64encode( signature ).decode( "utf-8" ), contentToSign.decode( "utf-8" ) ) if useNewKey: return "--rbxsig2%{}%{}".format( base64.b64encode( signature ).decode( "utf-8" ), contentToSign.decode( "utf-8" ) ) return "--rbxsig%{}%{}".format( base64.b64encode( signature ).decode( "utf-8" ), contentToSign.decode( "utf-8" ) ) else: return signature