1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
| import base64 import struct
class RC6: def __init__(self, key, rounds=20, word_size=32): self.rounds = rounds self.word_size = word_size self.mod = 2 ** word_size self.block_size = 16 self.S = self._expand_key(key) def _expand_key(self, key): if len(key) < 16: pad_len = 16 - len(key) key = key + bytes([pad_len] * pad_len) elif len(key) > 16: key = key[:16] P = 0xB7E15163 Q = 0x9E3779B9 c = 4 L = [0] * c for i in range(c): word_bytes = key[i*4:(i+1)*4] L[i] = struct.unpack('<I', word_bytes)[0] t = 2 * (self.rounds + 2) S = [P] for i in range(1, t): S.append((S[i-1] + Q) % self.mod) A = B = 0 i = j = 0 v = 3 * max(t, c) for _ in range(v): A = S[i] = self._rotl((S[i] + A + B) % self.mod, 3, self.word_size) B = L[j] = self._rotl((L[j] + A + B) % self.mod, (A + B) % self.word_size, self.word_size) i = (i + 1) % t j = (j + 1) % c return S @staticmethod def _rotl(x, n, w): n %= w return ((x << n) & ((1 << w) - 1)) | (x >> (w - n)) @staticmethod def _rotr(x, n, w): n %= w return (x >> n) | ((x << (w - n)) & ((1 << w) - 1)) def decrypt_block(self, block): if len(block) != self.block_size: raise ValueError(f"Block must be {self.block_size} bytes") A, B, C, D = struct.unpack('<4I', block) C = (C - self.S[2*self.rounds+3]) % self.mod A = (A - self.S[2*self.rounds+2]) % self.mod for i in range(self.rounds, 0, -1): A, B, C, D = D, A, B, C u = self._rotl((D * (2*D + 1)) % self.mod, 5, self.word_size) t = self._rotl((B * (2*B + 1)) % self.mod, 5, self.word_size) C = self._rotr((C - self.S[2*i+1]) % self.mod, t % self.word_size, self.word_size) ^ u A = self._rotr((A - self.S[2*i]) % self.mod, u % self.word_size, self.word_size) ^ t D = (D - self.S[1]) % self.mod B = (B - self.S[0]) % self.mod return struct.pack('<4I', A, B, C, D) def decrypt_cbc(self, ciphertext, iv): blocks = [ciphertext[i:i+self.block_size] for i in range(0, len(ciphertext), self.block_size)] plaintext = b'' prev = iv for block in blocks: decrypted_block = self.decrypt_block(block) plaintext_block = bytes(a ^ b for a, b in zip(decrypted_block, prev)) plaintext += plaintext_block prev = block return plaintext
def main(): key = b"FSZ36f3vU8s5" iv = b"WcE4Bbm4kHYQsAcX" ciphertext_b64 = "RKCTaz+fty1J2qsz4DI6t9bmMiLBxqFrpI70fU4IMemczIlM+z1IoVQobIt1MbXF" ciphertext = base64.b64decode(ciphertext_b64) rc6 = RC6(key, rounds=20) raw_plaintext = rc6.decrypt_cbc(ciphertext, iv) pad_len = raw_plaintext[-1] if 1 <= pad_len <= 16: license_key = raw_plaintext[:-pad_len].decode('utf-8') print(license_key) else: print(raw_plaintext.decode('utf-8', errors='replace'))
if __name__ == "__main__": main()
|