def decode_oaep(enc, key): modulus = int(key, 16) key = RSA.construct((modulus, Otp.exponent)) cipher = oaep.new(key, hash_algo=Hash.SHA256) block_size = 128 dec_string = "" enc_b = bytes.fromhex(enc) nb_block = ceil(len(enc_b) / block_size) for x in range(0, nb_block): if x == nb_block - 1: maxi = len(enc_b) else: maxi = (1 + x) * 128 mini = x * 128 ciphertext = cipher.decrypt(enc_b[mini:maxi]) dec_string += ciphertext.hex() logger.debug(dec_string) return dec_string
def init(self, Kfact=None, Kiw=None, pinmode=None): self.Kfact = Kfact self.pinmode = pinmode self.Kiw = self.decode_oaep(Kiw, self.Kfact) key = RSA.construct((int(self.Kiw, 16), Otp.exponent)) self.cipher = oaep.new(key, hash_algo=Hash.SHA256)
def encode_oeap(text, key): cipher = oaep.new(bytes.fromhex(key), hash_algo=Hash.SHA256) return cipher.encrypt(text)
def __setstate__(self, dict_param): self.__dict__.update(dict_param) if self.Kiw is not None: key = RSA.construct((int(self.Kiw, 16), Otp.exponent)) self.cipher = oaep.new(key, hash_algo=Hash.SHA256)
def activation_finalyze(self, random_bytes=None): R = self.get_r() params = {"action": "ActionFinalize", "mode": self.mode, "id": self.data.iwid, "lastsync": self.data.iwTsync, "version": "Generator-1.0/0.2.11", "lang": "fr", "ack": "", "macid": self.macid} if self.mode == Otp.OTP_MODE: params.update({"keytype": '0', "sid": self.data.iwsecid}) elif self.mode == Otp.ACTIVATE_MODE: kma_crypt = self.cipher.encrypt(bytes.fromhex(self.generate_kma(self.codepin))).hex() pin_crypt = self.cipher.encrypt(self.codepin.encode("utf-8")).hex() params.update({"serial": self.get_serial(), "code": self.smsCode, "Kma": kma_crypt, "pin": pin_crypt, "name": "Android SDK built for x86_64 / UNKNOWN", }) params.update(R) xml = self.request(params) if xml["err"] != "OK": return Otp.NOK self.data.synchro(xml, self.generate_kma(self.codepin)) if self.mode == Otp.OTP_MODE: try: self.defi = str(xml["defi"]) except KeyError: raise ConfigException if "J" in xml: logger.debug("Need another otp request") return Otp.OTP_TWICE return Otp.OK if "ms_n" not in xml or xml["ms_n"] == 0: logger.debug("no ms_n request needed") return Otp.OK if int(xml["ms_n"]) > 1: raise NotImplementedError ms_n = "0" self.challenge = xml["challenge"] self.action = "synchro" res = self.decode_oaep(xml["ms_key"], self.Kfact) temp_key = RSA.construct((int(res, 16), self.exponent)) temp_cipher = oaep.new(temp_key, hash_algo=Hash.SHA256) if random_bytes is None: random_bytes = token_bytes(16) kpub_encode = temp_cipher.encrypt(random_bytes) aes_cipher = AES.new(bytes.fromhex(self.generate_kma(self.codepin)), AES.MODE_ECB) encode_aes_from_hex = aes_cipher.encrypt(random_bytes).hex() self.data.iwsecval = encode_aes_from_hex self.data.iwsecid = xml["s_id"] self.data.iwsecn = 1 req_param = {"action": "ActionFinalize", "mode": Otp.MS_MODE, "ms_id" + ms_n: xml["ms_id"], "ms_val" + ms_n: kpub_encode.hex(), "macid": self.macid} req_param.update({"id": self.data.iwid, "lastsync": self.data.iwTsync, "ms_n": 1}) req_param.update(self.get_r()) xml = self.request(req_param) self.data.synchro(xml, self.generate_kma(self.codepin)) return Otp.OK