Exemplo n.º 1
0
    def encryptRsaWiener(msg: str):
        from Crypto.Util.number import getPrime, inverse
        from cryptostuff import encrypt

        bits = 2048
        dBits = 200

        bitsDifferencePQ = 50
        i = 0
        while True:
            p = getPrime(bits // 2 + bitsDifferencePQ)
            q = getPrime(bits // 2 - bitsDifferencePQ)
            d = getPrime(dBits)
            # print d
            e = inverse(d, (p - 1) * (q - 1))
            if len(str(hex(e)[2:])) * 4 < bits - 5:
                # Very hacky and not very accurate but it serves its purpose: We want to ensure that e is not relatively small in relation to n.
                # print "e too small."
                i += 1
                if i > 100:
                    raise Exception(
                        "Something is wrong in GameServerCrypto.encryptRsaWiener()"
                    )
                continue
            params = {"e": e, "n": p * q, "method": "saar"}
            msg += GameServerCrypto.parameterHash(params)
            return encrypt("saar", msg.encode("utf-8"), params), params, msg
Exemplo n.º 2
0
 def schwenkNew(msg: str, skipKeyAndIV=False):
     # import Crypto.Random
     import random
     import string
     from cryptostuff import encrypt
     if skipKeyAndIV:
         k = ""
         IV = ""
     else:
         k = "".join([
             random.choice(string.printable)
             for _ in range(Schwenk.BLOCK_SIZE)
         ])
         IV = "".join([
             random.choice(string.printable)
             for _ in range(Schwenk.BLOCK_SIZE)
         ])
     fakeHash = "".join(
         random.choice("0123456789abcdef") for _ in range(SHA512_HEX_LEN)
     )  # To be consistent with the other plaintext formats
     msg = k + IV + msg + fakeHash
     cipher, rawParams = Schwenk.encrypt(msg.encode("utf-8"))
     params = {
         "schwenkerid": rawParams[0],
         "schwenkingoptions": rawParams[1],
         "method": "schwenk"
     }
     cipher1 = encrypt("schwenk", msg.encode("utf-8"), params)
     assert cipher1 == cipher
     return cipher, params, msg
Exemplo n.º 3
0
    def encryptCaesar(msg: str):
        import random
        from cryptostuff import encrypt

        key = random.randint(-2**31, 2**31)
        params = {"key": key, "method": "caesar"}
        msg += GameServerCrypto.parameterHash(params)
        return encrypt("caesar", msg.encode("utf-8"), params), params, msg
Exemplo n.º 4
0
    def encryptOTP(msg: str):
        from cryptostuff import encrypt

        numBytes = len(msg) + 512 // 4
        with open("/dev/urandom", "rb") as f:
            randBytes = f.read(numBytes)
        params = {"encryptionkey": hexlify(randBytes).decode("utf-8"), "method": "otp"}
        msg += GameServerCrypto.parameterHash(params)
        return encrypt("otp", msg.encode("utf-8"), params), params, msg
Exemplo n.º 5
0
    def checkEncryption(msg: str, cipher: bytes, params: dict):
        from cryptostuff import encrypt

        if params["method"] == "elgamal":
            # As the encryption is randomized, we cannot simply encrypt the known plaintext and compare the ciphertexts...
            # TODO: I don't think we can properly check this. With the known plaintext only. Otherwise, ElGamal would be pretty broken.
            pass
        else:
            cTest = encrypt(params["method"], msg.encode("utf-8"), params)
            if cTest != cipher:
                raise FlagMissingException(f"Incorrect cipher. Got {repr(cipher)}, expected {repr(cTest)}")
            return
Exemplo n.º 6
0
    def processCommand(self, message: str, signature: bytes):
        print("received message:", message, file=sys.stderr)
        msg = json.loads(message)
        if "command" not in msg:
            return ERROR_INVALID_COMMAND
        command = msg["command"]
        try:
            if command == "db_retrieve_item":
                time.sleep(5)
                dbId = msg["data"]
                item = self.loadItem(dbId)
                if item is None:
                    return ERROR_INVALID_ITEM
                return '{"status":"db_retrieve_success", "data":"' + hexlify(
                    item[0]).decode("utf-8") + '","params":' + json.dumps(
                        item[1]) + '}'

            elif command == "db_store_item":
                if not self.isMessageFromTrustedClient(message, signature):
                    return ERROR_INVALID_CLIENT
                id = msg["id"]
                params = msg["params"]
                cipher = unhexlify(msg["cipher"])
                try:
                    self.storeItem(id, cipher, params)
                except IntegrityError:
                    return ERROR_ITEM_EXISTS
                return '{"status":"db_store_success"}'

            elif command == "check_item":
                if not self.isMessageFromTrustedClient(message, signature):
                    return ERROR_INVALID_CLIENT
                dbId = msg["id"]
                item = self.loadItem((dbId))
                if item is None:
                    return ERROR_INVALID_ITEM
                c, params = item
                p = msg["msg"].encode("utf-8")
                try:
                    c1 = cryptostuff.encrypt(params["method"], p, params)
                    if c != c1:
                        return '{"status":"check_fail"}'
                    return '{"status":"check_success"}'
                except:
                    return '{"status":"check_fail"}'

            else:
                return ERROR_INVALID_COMMAND
        except Exception as e:
            return ERROR_INTERNAL_SERVER_ERROR % (type(e), e)
Exemplo n.º 7
0
    def encryptRsaSmallFactor(msg: str):
        # We have a non-negligible probability for the message not being coprime to n. Hence, we need to check for this case.
        from Crypto.Util.number import getPrime, GCD, bytes_to_long
        from cryptostuff import encrypt

        bits = 2048
        smallFactorBits = 10
        e = 65537
        i = 0
        while True:
            bigFactorBits = bits - smallFactorBits
            p = getPrime(smallFactorBits)
            q = getPrime(bigFactorBits)
            n = p * q
            params = {"e": e, "n": n, "method": "saar"}
            m = msg + GameServerCrypto.parameterHash(params)
            if GCD(bytes_to_long(m.encode("utf-8")), n) == 1:
                return encrypt("saar", m.encode("utf-8"), params), params, m
            i += 1
            if i > 50:
                raise Exception("Something is wrong in GameServerCrypto.encryptRsaSmallFactor()")
Exemplo n.º 8
0
    def checkEncryption(msg: str, cipher: bytes, params: dict):
        from cryptostuff import encrypt
        from cryptostuff import methods as encryptMethods
        if "method" not in params:
            raise MumbleException('Missing key: "method"')

        if params["method"] not in encryptMethods:
            raise MumbleException(f'Unknown method: "{params["method"]}"')
        if params["method"] == "elgamal":
            # As the encryption is randomized, we cannot simply encrypt the known plaintext and compare the ciphertexts...
            # TODO: I don't think we can properly check this. With the known plaintext only. Otherwise, ElGamal would be pretty broken.
            pass
        else:
            try:
                cTest = encrypt(params["method"], msg.encode("utf-8"), params)
            except Exception as e:
                raise MumbleException(
                    f"Got exception {e} of type {type(e)} during encryption.")
            if cTest != cipher:
                raise FlagMissingException(
                    f"Incorrect cipher. Got {repr(cipher)}, expected {repr(cTest)}. Params: "
                    + str(params))
            return
Exemplo n.º 9
0
    def encryptPlain(msg: str):
        from cryptostuff import encrypt

        params = {"method": "plain"}
        msg += GameServerCrypto.parameterHash(params)
        return encrypt("plain", msg.encode("utf-8"), params), params, msg