Kekik 1.5.3__tar.gz → 1.5.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of Kekik might be problematic. Click here for more details.

Files changed (48) hide show
  1. {kekik-1.5.3 → kekik-1.5.4}/Kekik/Sifreleme/AESManager.py +16 -1
  2. kekik-1.5.4/Kekik/Sifreleme/CryptoJS.py +99 -0
  3. kekik-1.5.4/Kekik/Sifreleme/NaysHash.py +66 -0
  4. {kekik-1.5.3 → kekik-1.5.4}/Kekik/Sifreleme/__init__.py +2 -1
  5. {kekik-1.5.3 → kekik-1.5.4}/Kekik.egg-info/PKG-INFO +1 -1
  6. {kekik-1.5.3 → kekik-1.5.4}/Kekik.egg-info/SOURCES.txt +1 -0
  7. {kekik-1.5.3 → kekik-1.5.4}/PKG-INFO +1 -1
  8. {kekik-1.5.3 → kekik-1.5.4}/setup.py +1 -1
  9. kekik-1.5.3/Kekik/Sifreleme/CryptoJS.py +0 -87
  10. {kekik-1.5.3 → kekik-1.5.4}/Kekik/BIST.py +0 -0
  11. {kekik-1.5.3 → kekik-1.5.4}/Kekik/Domain2IP.py +0 -0
  12. {kekik-1.5.3 → kekik-1.5.4}/Kekik/Nesne.py +0 -0
  13. {kekik-1.5.3 → kekik-1.5.4}/Kekik/Sifreleme/HexCodec.py +0 -0
  14. {kekik-1.5.3 → kekik-1.5.4}/Kekik/Sifreleme/Packer.py +0 -0
  15. {kekik-1.5.3 → kekik-1.5.4}/Kekik/Sifreleme/StringCodec.py +0 -0
  16. {kekik-1.5.3 → kekik-1.5.4}/Kekik/__init__.py +0 -0
  17. {kekik-1.5.3 → kekik-1.5.4}/Kekik/cli.py +0 -0
  18. {kekik-1.5.3 → kekik-1.5.4}/Kekik/csv2dict.py +0 -0
  19. {kekik-1.5.3 → kekik-1.5.4}/Kekik/dict2csv.py +0 -0
  20. {kekik-1.5.3 → kekik-1.5.4}/Kekik/dict2json.py +0 -0
  21. {kekik-1.5.3 → kekik-1.5.4}/Kekik/dosya2set.py +0 -0
  22. {kekik-1.5.3 → kekik-1.5.4}/Kekik/dosya_indir.py +0 -0
  23. {kekik-1.5.3 → kekik-1.5.4}/Kekik/hwid_kontrol.py +0 -0
  24. {kekik-1.5.3 → kekik-1.5.4}/Kekik/kisi_ver/__init__.py +0 -0
  25. {kekik-1.5.3 → kekik-1.5.4}/Kekik/kisi_ver/biyografiler.py +0 -0
  26. {kekik-1.5.3 → kekik-1.5.4}/Kekik/kisi_ver/isimler.py +0 -0
  27. {kekik-1.5.3 → kekik-1.5.4}/Kekik/kisi_ver/soyisimler.py +0 -0
  28. {kekik-1.5.3 → kekik-1.5.4}/Kekik/link_islemleri.py +0 -0
  29. {kekik-1.5.3 → kekik-1.5.4}/Kekik/list2html.py +0 -0
  30. {kekik-1.5.3 → kekik-1.5.4}/Kekik/liste_fetis.py +0 -0
  31. {kekik-1.5.3 → kekik-1.5.4}/Kekik/mail_gonder.py +0 -0
  32. {kekik-1.5.3 → kekik-1.5.4}/Kekik/okunabilir_byte.py +0 -0
  33. {kekik-1.5.3 → kekik-1.5.4}/Kekik/proxy_ver.py +0 -0
  34. {kekik-1.5.3 → kekik-1.5.4}/Kekik/qr_ver.py +0 -0
  35. {kekik-1.5.3 → kekik-1.5.4}/Kekik/ses_fetis.py +0 -0
  36. {kekik-1.5.3 → kekik-1.5.4}/Kekik/slugify.py +0 -0
  37. {kekik-1.5.3 → kekik-1.5.4}/Kekik/terminal_baslik.py +0 -0
  38. {kekik-1.5.3 → kekik-1.5.4}/Kekik/txt_fetis.py +0 -0
  39. {kekik-1.5.3 → kekik-1.5.4}/Kekik/unicode_tr.py +0 -0
  40. {kekik-1.5.3 → kekik-1.5.4}/Kekik/zaman_donustur.py +0 -0
  41. {kekik-1.5.3 → kekik-1.5.4}/Kekik.egg-info/dependency_links.txt +0 -0
  42. {kekik-1.5.3 → kekik-1.5.4}/Kekik.egg-info/entry_points.txt +0 -0
  43. {kekik-1.5.3 → kekik-1.5.4}/Kekik.egg-info/requires.txt +0 -0
  44. {kekik-1.5.3 → kekik-1.5.4}/Kekik.egg-info/top_level.txt +0 -0
  45. {kekik-1.5.3 → kekik-1.5.4}/LICENSE +0 -0
  46. {kekik-1.5.3 → kekik-1.5.4}/MANIFEST.in +0 -0
  47. {kekik-1.5.3 → kekik-1.5.4}/README.md +0 -0
  48. {kekik-1.5.3 → kekik-1.5.4}/setup.cfg +0 -0
@@ -63,4 +63,19 @@ class AESManager:
63
63
  cipher = AES.new(key, AES.MODE_CBC, iv)
64
64
  decrypted = unpad(cipher.decrypt(b64decode(data["ct"])), AES.block_size)
65
65
 
66
- return decrypted.decode("utf-8")
66
+ return decrypted.decode("utf-8")
67
+
68
+
69
+
70
+ # veri = r'''
71
+ # $(document).ready(function() {
72
+ # bePlayer('S3JScTBsNzMyYlFSMHg4NG5vQXNjUT09', '{"ct":"SjkWeIotWbL6TmnwyhkeLy6wAWvEG1pz8R0g+IsLN6P1vo9WvXuiqqDal5g6FXW3Td+Q+1DIGQAt3sNxydOAr4p3uFxxpVPUwIMwLWzw+5m0ED0tno1KU0\/rCXRwq6ATvmrIqSr+qb95hY0wjm3gfjPsxDn4vJ1fcdiRwrfC38MjfKyJFN3\/n\/xLvNT4vgQJTYTEmNOzFZgEIhsSRFiW1\/8nQCaS\/8Xkw0ySUqLvzSMsVf2SSgXyESxyksn3+kz9KqEI+mQpJFUcLSBz8VKXly+tEcYGpTQChzceyudkZcEGvppKheBAarEQ6e3eR9d04gQcFpEaV+QmHODvI1Ql\/pJ1FSAh9F5ZDtF00XDSLZbIEt00PWRkgfc3kxuNQzcC1C6BULNdoGwHbvo5W6uUsMwxG+sn+EH7B7jWtyhx5VHKpIfkyrjC10+K\/hG29bkS3YNSTaDxJnTa3jj1usbwwMX0A7wApIlce4rEVgWpO5y1ZuiJ+tEE3kH1InUzT1jfY4Y0KrZ5X+p2nrQhJrDOxfDy\/GhaidNmmpfuzF6Iniko6sCGa0QRbhVB8ZbrC9qFB\/sk47ZOP1IHPY\/jCh4BTFMDCy1Qx1\/PbVLZzNLHju\/cLYRzS0vJp5aqkwg\/QNCo1q5HrxXL32lMLNOcWPRDqyZaMpiYP+LzJPVndLsqGlfKJWETuKonEqc4r4M0Eu\/bTji\/S7zQ7bvEPuT3PyIRWXDffuNSX6+nqWFD8LM\/iNyc1cC3bMi+p0TR3YZu1MlIvxjYPK0lYtDvd+vaYgCotFm0lLsqg5cuw3pGb8jnEfM1VzEqDcBvBTkRKrxIao\/WWdvGf1MCmTsr+nVH0sT8PTrh6XcoG7hV\/+y8XCsEj2LKWtDtfK+RxSztteXYUUUI9NVtCvjlW\/b8+h6u+B\/CNLtrwoDQzKhTVZ1rZbe\/TP+HR7SkMXYqyAX3qqiyi9s+TrcqkxdbAHzkjr0q2DshtUeipcL5HVrdxL28iXqtYMT\/ytsRCQHpnswNGqW+D47VAYtDl4VafSaNGUMPfu6nq4k0\/FrxtYkts4lE9YUkueQHip8eOFO8dxTp8O7+Civt88C45wEjBHqaiN+n6wm1+3xUy2hKX0PD4gvlPuUeoHDbm\/HLUlPYmGw5cCEAskuJRXdW+gnFB6XzVIKrF7OUtd2yLqSLhnWcSFkMJoPDuIezn1D60pMi8LlJKb1HXwbPRRcqh00\/bFNdmodGpwybcaeegvRaCJbDqd6fmQUxG1ir9o5O8st2\/oJ9\/HivYvxi\/sicZYNzFtuZFGC\/ubPK5Ld9RsJb\/RQ9rkTZzhkBnmM=","iv":"2fedfd8ae68165490f274b521d5a3291","s":"74a525e8e5746772"}');
73
+ # });
74
+ # '''
75
+
76
+ # be_player = search(r"bePlayer\('([^']+)',\s*'(\{[^\}]+\})'\);", veri).groups()
77
+ # be_player_pass = be_player[0]
78
+ # be_player_data = be_player[1]
79
+
80
+ # encrypted = AESManager.decrypt(be_player_data, be_player_pass).replace("\\", "")
81
+ # print(json.loads(encrypted))
@@ -0,0 +1,99 @@
1
+ # ! Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
+
3
+ from Crypto.Cipher import AES
4
+ from Crypto.Random import get_random_bytes
5
+ import hashlib, base64
6
+
7
+ class CryptoJS:
8
+ """
9
+ Paroladan türetilmiş anahtar ile AES/CBC/PKCS7Padding şifreleme ve şifre çözme işlemleri için bir sınıf.
10
+ CryptoJS AES yöntemine uygundur.
11
+ ! » https://gist.github.com/thackerronak/554c985c3001b16810af5fc0eb5c358f
12
+ """
13
+ KEY_SIZE = 32
14
+ IV_SIZE = 16
15
+ HASH_CIPHER = "AES/CBC/PKCS7Padding"
16
+ AES_MODE = AES.MODE_CBC
17
+ KDF_DIGEST = "md5"
18
+ APPEND = b"Salted__"
19
+
20
+ @staticmethod
21
+ def evp_kdf(password, salt, key_size=32, iv_size=16, iterations=1, hash_algorithm="md5"):
22
+ """Paroladan Anahtar ve IV oluşturmak için bir KDF fonksiyonu."""
23
+ target_key_size = key_size + iv_size
24
+ derived_bytes = b""
25
+ block = None
26
+
27
+ while len(derived_bytes) < target_key_size:
28
+ hasher = hashlib.new(hash_algorithm)
29
+ if block:
30
+ hasher.update(block)
31
+
32
+ hasher.update(password)
33
+ hasher.update(salt)
34
+ block = hasher.digest()
35
+
36
+ for _ in range(1, iterations):
37
+ block = hashlib.new(hash_algorithm, block).digest()
38
+
39
+ derived_bytes += block
40
+
41
+ return derived_bytes[:key_size], derived_bytes[key_size:key_size + iv_size]
42
+
43
+ @staticmethod
44
+ def encrypt(password, plain_text):
45
+ """Verilen metni AES/CBC/PKCS7Padding şifreleme yöntemi ile şifreler."""
46
+ salt = CryptoJS.generate_salt(8)
47
+ key, iv = CryptoJS.evp_kdf(password.encode("utf-8"), salt, key_size=CryptoJS.KEY_SIZE, iv_size=CryptoJS.IV_SIZE)
48
+
49
+ cipher = AES.new(key, CryptoJS.AES_MODE, iv)
50
+ cipher_text = cipher.encrypt(CryptoJS._pad(plain_text.encode("utf-8")))
51
+
52
+ # Create CryptoJS-like encrypted output
53
+ encrypted_data = CryptoJS.APPEND + salt + cipher_text
54
+
55
+ return base64.b64encode(encrypted_data).decode("utf-8")
56
+
57
+ @staticmethod
58
+ def decrypt(password, cipher_text):
59
+ """Verilen şifreli metni AES/CBC/PKCS7Padding şifreleme yöntemi ile çözer."""
60
+ ct_bytes = base64.b64decode(cipher_text)
61
+ salt = ct_bytes[8:16]
62
+ cipher_text_bytes = ct_bytes[16:]
63
+
64
+ key, iv = CryptoJS.evp_kdf(password.encode("utf-8"), salt, key_size=CryptoJS.KEY_SIZE, iv_size=CryptoJS.IV_SIZE)
65
+
66
+ cipher = AES.new(key, CryptoJS.AES_MODE, iv)
67
+ plain_text = cipher.decrypt(cipher_text_bytes)
68
+
69
+ return CryptoJS._unpad(plain_text).decode("utf-8")
70
+
71
+ @staticmethod
72
+ def _pad(s):
73
+ """Veriyi AES blok boyutuna göre doldurur (PKCS7)."""
74
+ block_size = AES.block_size
75
+ padding = block_size - len(s) % block_size
76
+
77
+ return s + bytes([padding] * padding)
78
+
79
+ @staticmethod
80
+ def _unpad(s):
81
+ """Dolguyu kaldırır (PKCS7)."""
82
+ return s[:-ord(s[-1:])]
83
+
84
+ @staticmethod
85
+ def generate_salt(length):
86
+ """Belirtilen uzunlukta rastgele bir tuz oluşturur."""
87
+ return get_random_bytes(length)
88
+
89
+
90
+
91
+ # veri = r'''
92
+ # <script type="text/javascript">var bytes = CryptoJS.AES.decrypt("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");document.write(bytes.toString(CryptoJS.enc.Utf8));</script>
93
+ # '''
94
+
95
+ # cryptData = re.search(r"CryptoJS\.AES\.decrypt\(\"(.*)\",\"", veri).group(1)
96
+ # cryptPass = re.search(r"\",\"(.*)\"\);", veri).group(1)
97
+
98
+ # decrypted = CryptoJS.decrypt(cryptPass, cryptData)
99
+ # print(decrypted)
@@ -0,0 +1,66 @@
1
+ # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
+
3
+ from Crypto.Cipher import AES
4
+ from Crypto.Util.Padding import unpad
5
+ from hmac import new as hmac
6
+ from hashlib import sha256
7
+ from base64 import b64decode, b64encode
8
+ from json import dumps
9
+
10
+ class NaysHash:
11
+ """
12
+ HMAC-SHA256 hash üretimi ve API token'ı oluşturma işlemleri için bir sınıf.
13
+ Şifreleme ve hash işlemlerinde kullanılan anahtarlar ve yöntemler hakkında bilgi sağlar.
14
+ # ! https://gist.github.com/keyiflerolsun/e91c6d6f19e79b5cd4cbc73833f74e72
15
+ """
16
+ def __init__(self, default_key:str="+KbPdSgVkYp3s6v9y=B&E)H@McQfThWm", application_key:str="y3o2R7UZg13nVqFAg+B9IVj61M62CLJSw0kPoy3RBJ9kISt0MSU9BBDy7SBUL7MK") -> None:
17
+ # HMAC için kullanılacak anahtarı deşifrele
18
+ self.hmac_key = self.decrypt_aes_cbc_pkcs7(
19
+ encrypted_text = application_key,
20
+ secret_key = default_key
21
+ )
22
+
23
+ def decrypt_aes_cbc_pkcs7(self, encrypted_text:str, secret_key:str) -> str:
24
+ # Şifrelenmiş metni ve anahtarı bayt dizisine çevir
25
+ encrypted_text_bytes = b64decode(encrypted_text.encode("utf-8"))
26
+ key_bytes = secret_key.encode("utf-8")
27
+
28
+ # İlk vektörü (IV) ve şifre çözücüyü (cipher) oluştur
29
+ iv = key_bytes[:16]
30
+ cipher = AES.new(key_bytes, AES.MODE_CBC, iv)
31
+
32
+ # Metni deşifre et
33
+ decrypted_bytes = unpad(cipher.decrypt(encrypted_text_bytes), AES.block_size)
34
+ return decrypted_bytes.decode("utf-8")
35
+
36
+ def generate_hash_with_hmac256(self, msg:str):
37
+ # Verilen mesaj için HMAC-SHA256 hash oluştur
38
+ hmac256_hash = hmac(
39
+ key = self.hmac_key.encode("utf-8"),
40
+ msg = msg.encode("utf-8"),
41
+ digestmod = sha256
42
+ )
43
+
44
+ return b64encode(hmac256_hash.digest()).decode("utf-8")
45
+
46
+ def generate_xtoken(self, endpoint:str, payload:dict, timestamp:int) -> str:
47
+ # API isteği için "xtoken" oluştur
48
+ return self.generate_hash_with_hmac256(
49
+ f"{endpoint}{dumps(payload, ensure_ascii=False, sort_keys=False)}{timestamp}".replace(" ", "")
50
+ )
51
+
52
+
53
+
54
+ # print(NaysHash().generate_xtoken(
55
+ # timestamp = 1695076755128,
56
+ # endpoint = "/customer-citizen-info-v3",
57
+ # payload = {
58
+ # "birthDay" : 31,
59
+ # "birthMonth" : 1,
60
+ # "birthYear" : 1990,
61
+ # "citizenId" : "11111111111",
62
+ # "customerName" : "merhaba",
63
+ # "customerSurname" : "dünya",
64
+ # "explicitConsentSigned" : True
65
+ # },
66
+ # ))
@@ -4,4 +4,5 @@ from .StringCodec import StringCodec
4
4
  from .AESManager import AESManager
5
5
  from .Packer import Packer
6
6
  from .CryptoJS import CryptoJS
7
- from .HexCodec import HexCodec
7
+ from .HexCodec import HexCodec
8
+ from .NaysHash import NaysHash
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: Kekik
3
- Version: 1.5.3
3
+ Version: 1.5.4
4
4
  Summary: İşlerimizi kolaylaştıracak fonksiyonların el altında durduğu kütüphane..
5
5
  Home-page: https://github.com/keyiflerolsun/Kekik
6
6
  Author: keyiflerolsun
@@ -35,6 +35,7 @@ Kekik.egg-info/top_level.txt
35
35
  Kekik/Sifreleme/AESManager.py
36
36
  Kekik/Sifreleme/CryptoJS.py
37
37
  Kekik/Sifreleme/HexCodec.py
38
+ Kekik/Sifreleme/NaysHash.py
38
39
  Kekik/Sifreleme/Packer.py
39
40
  Kekik/Sifreleme/StringCodec.py
40
41
  Kekik/Sifreleme/__init__.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: Kekik
3
- Version: 1.5.3
3
+ Version: 1.5.4
4
4
  Summary: İşlerimizi kolaylaştıracak fonksiyonların el altında durduğu kütüphane..
5
5
  Home-page: https://github.com/keyiflerolsun/Kekik
6
6
  Author: keyiflerolsun
@@ -6,7 +6,7 @@ from io import open
6
6
  setup(
7
7
  # ? Genel Bilgiler
8
8
  name = "Kekik",
9
- version = "1.5.3",
9
+ version = "1.5.4",
10
10
  url = "https://github.com/keyiflerolsun/Kekik",
11
11
  description = "İşlerimizi kolaylaştıracak fonksiyonların el altında durduğu kütüphane..",
12
12
  keywords = ["Kekik", "KekikAkademi", "keyiflerolsun"],
@@ -1,87 +0,0 @@
1
- # ! Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
-
3
- from Crypto.Cipher import AES
4
- from Crypto.Random import get_random_bytes
5
- import hashlib, base64
6
-
7
- class CryptoJS:
8
- """
9
- Paroladan türetilmiş anahtar ile AES/CBC/PKCS7Padding şifreleme ve şifre çözme işlemleri için bir sınıf.
10
- CryptoJS AES yöntemine uygundur.
11
- ! » https://gist.github.com/thackerronak/554c985c3001b16810af5fc0eb5c358f
12
- """
13
- KEY_SIZE = 32
14
- IV_SIZE = 16
15
- HASH_CIPHER = "AES/CBC/PKCS7Padding"
16
- AES_MODE = AES.MODE_CBC
17
- KDF_DIGEST = "md5"
18
- APPEND = b"Salted__"
19
-
20
- @staticmethod
21
- def evp_kdf(password, salt, key_size=32, iv_size=16, iterations=1, hash_algorithm="md5"):
22
- """Paroladan Anahtar ve IV oluşturmak için bir KDF fonksiyonu."""
23
- target_key_size = key_size + iv_size
24
- derived_bytes = b""
25
- block = None
26
-
27
- while len(derived_bytes) < target_key_size:
28
- hasher = hashlib.new(hash_algorithm)
29
- if block:
30
- hasher.update(block)
31
-
32
- hasher.update(password)
33
- hasher.update(salt)
34
- block = hasher.digest()
35
-
36
- for _ in range(1, iterations):
37
- block = hashlib.new(hash_algorithm, block).digest()
38
-
39
- derived_bytes += block
40
-
41
- return derived_bytes[:key_size], derived_bytes[key_size:key_size + iv_size]
42
-
43
- @staticmethod
44
- def encrypt(password, plain_text):
45
- """Verilen metni AES/CBC/PKCS7Padding şifreleme yöntemi ile şifreler."""
46
- salt = CryptoJS.generate_salt(8)
47
- key, iv = CryptoJS.evp_kdf(password.encode("utf-8"), salt, key_size=CryptoJS.KEY_SIZE, iv_size=CryptoJS.IV_SIZE)
48
-
49
- cipher = AES.new(key, CryptoJS.AES_MODE, iv)
50
- cipher_text = cipher.encrypt(CryptoJS._pad(plain_text.encode("utf-8")))
51
-
52
- # Create CryptoJS-like encrypted output
53
- encrypted_data = CryptoJS.APPEND + salt + cipher_text
54
-
55
- return base64.b64encode(encrypted_data).decode("utf-8")
56
-
57
- @staticmethod
58
- def decrypt(password, cipher_text):
59
- """Verilen şifreli metni AES/CBC/PKCS7Padding şifreleme yöntemi ile çözer."""
60
- ct_bytes = base64.b64decode(cipher_text)
61
- salt = ct_bytes[8:16]
62
- cipher_text_bytes = ct_bytes[16:]
63
-
64
- key, iv = CryptoJS.evp_kdf(password.encode("utf-8"), salt, key_size=CryptoJS.KEY_SIZE, iv_size=CryptoJS.IV_SIZE)
65
-
66
- cipher = AES.new(key, CryptoJS.AES_MODE, iv)
67
- plain_text = cipher.decrypt(cipher_text_bytes)
68
-
69
- return CryptoJS._unpad(plain_text).decode("utf-8")
70
-
71
- @staticmethod
72
- def _pad(s):
73
- """Veriyi AES blok boyutuna göre doldurur (PKCS7)."""
74
- block_size = AES.block_size
75
- padding = block_size - len(s) % block_size
76
-
77
- return s + bytes([padding] * padding)
78
-
79
- @staticmethod
80
- def _unpad(s):
81
- """Dolguyu kaldırır (PKCS7)."""
82
- return s[:-ord(s[-1:])]
83
-
84
- @staticmethod
85
- def generate_salt(length):
86
- """Belirtilen uzunlukta rastgele bir tuz oluşturur."""
87
- return get_random_bytes(length)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes