├── .github └── workflows │ └── pr_notification.yml ├── LICENSE ├── README.md ├── keyauth.py ├── main.py ├── other-examples ├── README.md ├── merged_example.py ├── method1.py └── method2.py └── requirements.txt /.github/workflows/pr_notification.yml: -------------------------------------------------------------------------------- 1 | name: Pull Request Notification 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | 8 | jobs: 9 | notify: 10 | uses: KeyAuth/.github/.github/workflows/pr_notification_global.yml@main 11 | secrets: 12 | DISCORD_PR: ${{ secrets.DISCORD_PR }} 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Elastic License 2.0 2 | 3 | URL: https://www.elastic.co/licensing/elastic-license 4 | 5 | ## Acceptance 6 | 7 | By using the software, you agree to all of the terms and conditions below. 8 | 9 | ## Copyright License 10 | 11 | The licensor grants you a non-exclusive, royalty-free, worldwide, 12 | non-sublicensable, non-transferable license to use, copy, distribute, make 13 | available, and prepare derivative works of the software, in each case subject to 14 | the limitations and conditions below. 15 | 16 | ## Limitations 17 | 18 | You may not provide the software to third parties as a hosted or managed 19 | service, where the service provides users with access to any substantial set of 20 | the features or functionality of the software. 21 | 22 | You may not move, change, disable, or circumvent the license key functionality 23 | in the software, and you may not remove or obscure any functionality in the 24 | software that is protected by the license key. 25 | 26 | You may not alter, remove, or obscure any licensing, copyright, or other notices 27 | of the licensor in the software. Any use of the licensor’s trademarks is subject 28 | to applicable law. 29 | 30 | ## Patents 31 | 32 | The licensor grants you a license, under any patent claims the licensor can 33 | license, or becomes able to license, to make, have made, use, sell, offer for 34 | sale, import and have imported the software, in each case subject to the 35 | limitations and conditions in this license. This license does not cover any 36 | patent claims that you cause to be infringed by modifications or additions to 37 | the software. If you or your company make any written claim that the software 38 | infringes or contributes to infringement of any patent, your patent license for 39 | the software granted under these terms ends immediately. If your company makes 40 | such a claim, your patent license ends immediately for work on behalf of your 41 | company. 42 | 43 | ## Notices 44 | 45 | You must ensure that anyone who gets a copy of any part of the software from you 46 | also gets a copy of these terms. 47 | 48 | If you modify the software, you must include in any modified copies of the 49 | software prominent notices stating that you have modified the software. 50 | 51 | ## No Other Rights 52 | 53 | These terms do not imply any licenses other than those expressly granted in 54 | these terms. 55 | 56 | ## Termination 57 | 58 | If you use the software in violation of these terms, such use is not licensed, 59 | and your licenses will automatically terminate. If the licensor provides you 60 | with a notice of your violation, and you cease all violation of this license no 61 | later than 30 days after you receive that notice, your licenses will be 62 | reinstated retroactively. However, if you violate these terms after such 63 | reinstatement, any additional violation of these terms will cause your licenses 64 | to terminate automatically and permanently. 65 | 66 | ## No Liability 67 | 68 | *As far as the law allows, the software comes as is, without any warranty or 69 | condition, and the licensor will not be liable to you for any damages arising 70 | out of these terms or the use or nature of the software, under any kind of 71 | legal claim.* 72 | 73 | ## Definitions 74 | 75 | The **licensor** is the entity offering these terms, and the **software** is the 76 | software the licensor makes available under these terms, including any portion 77 | of it. 78 | 79 | **you** refers to the individual or entity agreeing to these terms. 80 | 81 | **your company** is any legal entity, sole proprietorship, or other kind of 82 | organization that you work for, plus all organizations that have control over, 83 | are under the control of, or are under common control with that 84 | organization. **control** means ownership of substantially all the assets of an 85 | entity, or the power to direct its management and policies by vote, contract, or 86 | otherwise. Control can be direct or indirect. 87 | 88 | **your licenses** are all the licenses granted to you for the software under 89 | these terms. 90 | 91 | **use** means anything you do with the software requiring one of your licenses. 92 | 93 | **trademark** means trademarks, service marks, and similar rights. 94 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KeyAuth-Python-Example : Please star 🌟 2 | 3 | KeyAuth Python example SDK for https://keyauth.cc license key API auth. 4 | 5 | ## **Bugs** 6 | 7 | If you are using our example with no significant changes, and you are having problems, please Report Bug here https://keyauth.cc/app/?page=forms 8 | 9 | However, we do **NOT** provide support for adding KeyAuth to your project. If you can't figure this out you should use Google or YouTube to learn more about the programming language you want to sell a program in. 10 | 11 | ## Copyright License 12 | 13 | KeyAuth is licensed under **Elastic License 2.0** 14 | 15 | * You may not provide the software to third parties as a hosted or managed 16 | service, where the service provides users with access to any substantial set of 17 | the features or functionality of the software. 18 | 19 | * You may not move, change, disable, or circumvent the license key functionality 20 | in the software, and you may not remove or obscure any functionality in the 21 | software that is protected by the license key. 22 | 23 | * You may not alter, remove, or obscure any licensing, copyright, or other notices 24 | of the licensor in the software. Any use of the licensor’s trademarks is subject 25 | to applicable law. 26 | 27 | Thank you for your compliance, we work hard on the development of KeyAuth and do not appreciate our copyright being infringed. 28 | 29 | ## **What is KeyAuth?** 30 | 31 | KeyAuth is an Open source authentication system with cloud hosting plans as well. Client SDKs available for [C#](https://github.com/KeyAuth/KeyAuth-CSHARP-Example), [C++](https://github.com/KeyAuth/KeyAuth-CPP-Example), [Python](https://github.com/KeyAuth/KeyAuth-Python-Example), [Java](https://github.com/KeyAuth-Archive/KeyAuth-JAVA-api), [JavaScript](https://github.com/mazkdevf/KeyAuth-JS-Example), [VB.NET](https://github.com/KeyAuth/KeyAuth-VB-Example), [PHP](https://github.com/KeyAuth/KeyAuth-PHP-Example), [Rust](https://github.com/KeyAuth/KeyAuth-Rust-Example), [Go](https://github.com/mazkdevf/KeyAuth-Go-Example), [Lua](https://github.com/mazkdevf/KeyAuth-Lua-Examples), [Ruby](https://github.com/mazkdevf/KeyAuth-Ruby-Example), and [Perl](https://github.com/mazkdevf/KeyAuth-Perl-Example). KeyAuth has several unique features such as memory streaming, webhook function where you can send requests to API without leaking the API, discord webhook notifications, ban the user securely through the application at your discretion. Feel free to join https://t.me/keyauth if you have questions or suggestions. 32 | 33 | > [!TIP] 34 | > https://vaultcord.com FREE Discord bot to Backup server, members, channels, messages & more. Custom verify page, block alt accounts, VPNs & more. 35 | 36 | ## **Customer connection issues?** 37 | 38 | This is common amongst all authentication systems. Program obfuscation causes false positives in virus scanners, and with the scale of KeyAuth this is perceived as a malicious domain. So, `keyauth.com` and `keyauth.win` have been blocked by many internet providers. for dashbord, reseller panel, customer panel, use `keyauth.cc` 39 | 40 | For API, `keyauth.cc` will not work because I purposefully blocked it on there so `keyauth.cc` doesn't get blocked also. So, you should create your own domain and follow this tutorial video https://www.youtube.com/watch?v=a2SROFJ0eYc. The tutorial video shows you how to create a domain name for 100% free if you don't want to purchase one. 41 | 42 | ## **How to compile?** 43 | 44 | You can either use Pyinstaller or Nuitka. 45 | 46 | Links: 47 | - Nuitka: https://nuitka.net/ 48 | - Pyinstaller: https://pyinstaller.org/ 49 | 50 | Pyinstaller: 51 | - Basic command: `pyinstaller --onefile main.py` 52 | 53 | Nutika: 54 | - Basic command: `python -m nuitka --follow-imports --onefile main.py` 55 | 56 | ## **`KeyAuthApp` instance definition** 57 | 58 | Visit https://keyauth.cc/app/ and select your application, then click on the **Python** tab 59 | 60 | It'll provide you with the code which you should replace with in the `main.py` file. 61 | 62 | ```PY 63 | keyauthapp = api( 64 | name = "", #App name (Manage Applications --> Application name) 65 | ownerid = "", #Owner ID (Account-Settings --> OwnerID) 66 | secret = "", #App secret(Manage Applications --> App credentials code) 67 | version = "", 68 | hash_to_check = getchecksum() 69 | ) 70 | ``` 71 | 72 | ## **Initialize application** 73 | 74 | You don't need to add any code to initalize. KeyAuth will initalize when the instance definition is made. 75 | 76 | ## **Display application information** 77 | 78 | ```py 79 | keyauthapp.fetchStats() 80 | print(f""" 81 | App data: 82 | Number of users: {keyauthapp.app_data.numUsers} 83 | Number of online users: {keyauthapp.app_data.onlineUsers} 84 | Number of keys: {keyauthapp.app_data.numKeys} 85 | Application Version: {keyauthapp.app_data.app_ver} 86 | Customer panel link: {keyauthapp.app_data.customer_panel} 87 | """) 88 | ``` 89 | 90 | ## **Check session validation** 91 | 92 | Use this to see if the user is logged in or not. 93 | 94 | ```py 95 | print(f"Current Session Validation Status: {keyauthapp.check()}") 96 | ``` 97 | 98 | ## **Check blacklist status** 99 | 100 | Check if HWID or IP Address is blacklisted. You can add this if you want, just to make sure nobody can open your program for less than a second if they're blacklisted. Though, if you don't mind a blacklisted user having the program for a few seconds until they try to login and register, and you care about having the quickest program for your users, you shouldn't use this function then. If a blacklisted user tries to login/register, the KeyAuth server will check if they're blacklisted and deny entry if so. So the check blacklist function is just auxiliary function that's optional. 101 | 102 | ```py 103 | if keyauthapp.checkblacklist(): 104 | print("You've been blacklisted from our application.") 105 | os._exit(1) 106 | ``` 107 | 108 | ## **Login with username/password** 109 | 110 | ```py 111 | user = input('Provide username: ') 112 | password = input('Provide password: ') 113 | keyauthapp.login(user, password) 114 | ``` 115 | 116 | ## **Register with username/password/key** 117 | 118 | ```py 119 | user = input('Provide username: ') 120 | password = input('Provide password: ') 121 | license = input('Provide License: ') 122 | keyauthapp.register(user, password, license) 123 | ``` 124 | 125 | ## **Upgrade user username/key** 126 | 127 | Used so the user can add extra time to their account by claiming new key. 128 | 129 | > [!Warning] 130 | > No password is needed to upgrade account. So, unlike login, register, and license functions - you should **not** log user in after successful upgrade. 131 | 132 | ```py 133 | user = input('Provide username: ') 134 | license = input('Provide License: ') 135 | keyauthapp.upgrade(user, license) 136 | ``` 137 | 138 | ## **Login with just license key** 139 | 140 | Users can use this function if their license key has never been used before, and if it has been used before. So if you plan to just allow users to use keys, you can remove the login and register functions from your code. 141 | 142 | ```py 143 | key = input('Enter your license: ') 144 | keyauthapp.license(key) 145 | ``` 146 | 147 | ## **User Data** 148 | 149 | Show information for current logged-in user. 150 | 151 | ```py 152 | print("\nUser data: ") 153 | print("Username: " + keyauthapp.user_data.username) 154 | print("IP address: " + keyauthapp.user_data.ip) 155 | print("Hardware-Id: " + keyauthapp.user_data.hwid) 156 | 157 | subs = keyauthapp.user_data.subscriptions # Get all Subscription names, expiry, and timeleft 158 | for i in range(len(subs)): 159 | sub = subs[i]["subscription"] # Subscription from every Sub 160 | expiry = datetime.utcfromtimestamp(int(subs[i]["expiry"])).strftime( 161 | '%Y-%m-%d %H:%M:%S') # Expiry date from every Sub 162 | timeleft = subs[i]["timeleft"] # Timeleft from every Sub 163 | 164 | print(f"[{i + 1} / {len(subs)}] | Subscription: {sub} - Expiry: {expiry} - Timeleft: {timeleft}") 165 | print("Created at: " + datetime.utcfromtimestamp(int(keyauthapp.user_data.createdate)).strftime('%Y-%m-%d %H:%M:%S')) 166 | print("Last login at: " + datetime.utcfromtimestamp(int(keyauthapp.user_data.lastlogin)).strftime('%Y-%m-%d %H:%M:%S')) 167 | print("Expires at: " + datetime.utcfromtimestamp(int(keyauthapp.user_data.expires)).strftime('%Y-%m-%d %H:%M:%S')) 168 | print(f"Current Session Validation Status: {keyauthapp.check()}") 169 | ``` 170 | 171 | ## **Show list of online users** 172 | 173 | ```py 174 | onlineUsers = keyauthapp.fetchOnline() 175 | OU = "" # KEEP THIS EMPTY FOR NOW, THIS WILL BE USED TO CREATE ONLINE USER STRING. 176 | if onlineUsers is None: 177 | OU = "No online users" 178 | else: 179 | for i in range(len(onlineUsers)): 180 | OU += onlineUsers[i]["credential"] + " " 181 | 182 | print("\n" + OU + "\n") 183 | ``` 184 | 185 | ## **Application variables** 186 | 187 | A string that is kept on the server-side of KeyAuth. On the dashboard you can choose for each variable to be authenticated (only logged in users can access), or not authenticated (any user can access before login). These are global and static for all users, unlike User Variables which will be dicussed below this section. 188 | 189 | ```py 190 | * Get normal variable and print it 191 | data = keyauthapp.var("varName") 192 | print(data) 193 | ``` 194 | 195 | ## **User Variables** 196 | 197 | User variables are strings kept on the server-side of KeyAuth. They are specific to users. They can be set on Dashboard in the Users tab, via SellerAPI, or via your loader using the code below. `discord` is the user variable name you fetch the user variable by. `test#0001` is the variable data you get when fetching the user variable. 198 | 199 | ```py 200 | * Set up user variable 201 | keyauthapp.setvar("varName", "varValue") 202 | ``` 203 | 204 | And here's how you fetch the user variable: 205 | 206 | ```py 207 | * Get user variable and print it 208 | data = keyauthapp.getvar("varName") 209 | print(data) 210 | ``` 211 | 212 | ## **Application Logs** 213 | 214 | Can be used to log data. Good for anti-debug alerts and maybe error debugging. If you set Discord webhook in the app settings of the Dashboard, it will send log messages to your Discord webhook rather than store them on site. It's recommended that you set Discord webhook, as logs on site are deleted 1 month after being sent. 215 | 216 | You can use the log function before login & after login. 217 | 218 | ```py 219 | * Log message to the server and then to your webhook what is set on app settings 220 | keyauthapp.log("Message") 221 | ``` 222 | 223 | ## **Ban the user** 224 | 225 | Ban the user and blacklist their HWID and IP Address. Good function to call upon if you use anti-debug and have detected an intrusion attempt. 226 | 227 | Function only works after login. 228 | 229 | ```py 230 | keyauthapp.ban() 231 | ``` 232 | 233 | ## **Enable Two Factor Authentication (2fa)** 234 | 235 | Enable two factor authentication (2fa) on a client account. 236 | 237 | ```py 238 | keyauthapp.enable2fa() 239 | ``` 240 | 241 | ## **Disable Two Factor Authentication (2fa)** 242 | 243 | Disable two factor authentication (2fa) on a client account. 244 | 245 | ```py 246 | keyauthapp.disable2fa() 247 | ``` 248 | 249 | ## **Logout session** 250 | 251 | Logout the users session and close the application. 252 | 253 | This only works if the user is authenticated (logged in) 254 | ```py 255 | keyauthapp.logout() 256 | ``` 257 | 258 | ## **Server-sided webhooks** 259 | 260 | Tutorial video https://www.youtube.com/watch?v=ENRaNPPYJbc 261 | 262 | > [!NOTE] 263 | > Read documentation for KeyAuth webhooks here https://keyauth.readme.io/reference/webhooks-1 264 | 265 | Send HTTP requests to URLs securely without leaking the URL in your application. You should definitely use if you want to send requests to SellerAPI from your application, otherwise if you don't use you'll be leaking your seller key to everyone. And then someone can mess up your application. 266 | 267 | 1st example is how to send request with no POST data. just a GET request to the URL. `7kR0UedlVI` is the webhook ID, `https://keyauth.win/api/seller/?sellerkey=sellerkeyhere&type=black` is what you should put as the webhook endpoint on the dashboard. This is the part you don't want users to see. And then you have `&ip=1.1.1.1&hwid=abc` in your program code which will be added to the webhook endpoint on the keyauth server and then the request will be sent. 268 | 269 | 2nd example includes post data. it is form data. it is an example request to the KeyAuth API. `7kR0UedlVI` is the webhook ID, `https://keyauth.win/api/1.2/` is the webhook endpoint. 270 | 271 | 3rd examples included post data though it's JSON. It's an example reques to Discord webhook `7kR0UedlVI` is the webhook ID, `https://discord.com/api/webhooks/...` is the webhook endpoint. 272 | 273 | ```py 274 | * example to send normal request with no POST data 275 | data = keyauthapp.webhook("7kR0UedlVI", "&ip=1.1.1.1&hwid=abc") 276 | 277 | * example to send form data 278 | data = keyauthapp.webhook("7kR0UedlVI", "", "type=init&name=test&ownerid=j9Gj0FTemM", "application/x-www-form-urlencoded") 279 | 280 | * example to send JSON 281 | data = keyauthapp.webhook("7kR0UedlVI", "", "{\"content\": \"webhook message here\",\"embeds\": null}", "application/json") 282 | ``` 283 | 284 | ## **Download file** 285 | 286 | > [!NOTE] 287 | > Read documentation for KeyAuth files here https://docs.keyauth.cc/website/dashboard/files 288 | 289 | Keep files secure by providing KeyAuth your file download link on the KeyAuth dashboard. Make sure this is a direct download link (as soon as you go to the link, it starts downloading without you clicking anything). The KeyAuth download function provides the bytes, and then you get to decide what to do with those. This example shows how to write it to a file named `text.txt` in the same folder as the program, though you could execute with RunPE or whatever you want. 290 | 291 | `385624` is the file ID you get from the dashboard after adding file. 292 | 293 | ```py 294 | * Download Files form the server to your computer using the download function in the api class 295 | bytes = keyauthapp.file("385624") 296 | f = open("example.exe", "wb") 297 | f.write(bytes) 298 | f.close() 299 | ``` 300 | 301 | ## **Chat channels** 302 | 303 | Allow users to communicate amongst themselves in your program. 304 | 305 | Example from the form example on how to fetch the chat messages. 306 | 307 | ```py 308 | * Get chat messages 309 | messages = keyauthapp.chatGet("CHANNEL") 310 | 311 | Messages = "" 312 | for i in range(len(messages)): 313 | Messages += datetime.utcfromtimestamp(int(messages[i]["timestamp"])).strftime('%Y-%m-%d %H:%M:%S') + " - " + messages[i]["author"] + ": " + messages[i]["message"] + "\n" 314 | 315 | print("\n\n" + Messages) 316 | ``` 317 | 318 | Example on how to send chat message. 319 | 320 | ```py 321 | * Send chat message 322 | keyauthapp.chatSend("MESSAGE", "CHANNEL") 323 | ``` 324 | 325 | Looking for a Discord bot made by the KeyAuth & RestoreCord founder that you can use to backup your Discord members, server settings, and messages? Go to https://vaultcord.com 326 | -------------------------------------------------------------------------------- /keyauth.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json as jsond # json 3 | import time # sleep before exit 4 | import binascii # hex encoding 5 | import platform # check platform 6 | import subprocess # needed for mac device 7 | import qrcode 8 | from datetime import datetime, timezone, timedelta 9 | from discord_interactions import verify_key # used for signature verification 10 | from PIL import Image 11 | 12 | 13 | try: 14 | if os.name == 'nt': 15 | import win32security # get sid (WIN only) 16 | import requests # https requests 17 | except ModuleNotFoundError: 18 | print("Exception when importing modules") 19 | print("Installing necessary modules....") 20 | if os.path.isfile("requirements.txt"): 21 | os.system("pip install -r requirements.txt") 22 | else: 23 | if os.name == 'nt': 24 | os.system("pip install pywin32") 25 | os.system("pip install requests") 26 | print("Modules installed!") 27 | time.sleep(1.5) 28 | os._exit(1) 29 | 30 | 31 | class api: 32 | 33 | name = ownerid = version = hash_to_check = "" 34 | 35 | def __init__(self, name, ownerid, version, hash_to_check): 36 | if len(ownerid) != 10: 37 | print("Visit https://keyauth.cc/app/, copy Pthon code, and replace code in main.py with that") 38 | time.sleep(3) 39 | os._exit(1) 40 | 41 | self.name = name 42 | 43 | self.ownerid = ownerid 44 | 45 | self.version = version 46 | self.hash_to_check = hash_to_check 47 | self.init() 48 | 49 | sessionid = enckey = "" 50 | initialized = False 51 | 52 | def init(self): 53 | if self.sessionid != "": 54 | print("You've already initialized!") 55 | time.sleep(3) 56 | os._exit(1) 57 | 58 | post_data = { 59 | "type": "init", 60 | "ver": self.version, 61 | "hash": self.hash_to_check, 62 | "name": self.name, 63 | "ownerid": self.ownerid 64 | } 65 | 66 | response = self.__do_request(post_data) 67 | 68 | if response == "KeyAuth_Invalid": 69 | print("The application doesn't exist") 70 | time.sleep(3) 71 | os._exit(1) 72 | 73 | json = jsond.loads(response) 74 | 75 | if json["message"] == "invalidver": 76 | if json["download"] != "": 77 | print("New Version Available") 78 | download_link = json["download"] 79 | os.system(f"start {download_link}") 80 | time.sleep(3) 81 | os._exit(1) 82 | else: 83 | print("Invalid Version, Contact owner to add download link to latest app version") 84 | time.sleep(3) 85 | os._exit(1) 86 | 87 | if not json["success"]: 88 | print(json["message"]) 89 | time.sleep(3) 90 | os._exit(1) 91 | 92 | self.sessionid = json["sessionid"] 93 | self.initialized = True 94 | 95 | def register(self, user, password, license, hwid=None): 96 | self.checkinit() 97 | if hwid is None: 98 | hwid = others.get_hwid() 99 | 100 | post_data = { 101 | "type": "register", 102 | "username": user, 103 | "pass": password, 104 | "key": license, 105 | "hwid": hwid, 106 | "sessionid": self.sessionid, 107 | "name": self.name, 108 | "ownerid": self.ownerid 109 | } 110 | 111 | response = self.__do_request(post_data) 112 | 113 | json = jsond.loads(response) 114 | 115 | if json["success"]: 116 | print(json["message"]) 117 | self.__load_user_data(json["info"]) 118 | else: 119 | print(json["message"]) 120 | time.sleep(3) 121 | os._exit(1) 122 | 123 | def upgrade(self, user, license): 124 | self.checkinit() 125 | 126 | post_data = { 127 | "type": "upgrade", 128 | "username": user, 129 | "key": license, 130 | "sessionid": self.sessionid, 131 | "name": self.name, 132 | "ownerid": self.ownerid 133 | } 134 | 135 | response = self.__do_request(post_data) 136 | 137 | json = jsond.loads(response) 138 | 139 | if json["success"]: 140 | print(json["message"]) 141 | print("Please restart program and login") 142 | time.sleep(3) 143 | os._exit(1) 144 | else: 145 | print(json["message"]) 146 | time.sleep(3) 147 | os._exit(1) 148 | 149 | def login(self, user, password, code=None, hwid=None): 150 | self.checkinit() 151 | if hwid is None: 152 | hwid = others.get_hwid() 153 | 154 | post_data = { 155 | "type": "login", 156 | "username": user, 157 | "pass": password, 158 | "hwid": hwid, 159 | "sessionid": self.sessionid, 160 | "name": self.name, 161 | "ownerid": self.ownerid, 162 | } 163 | 164 | if code is not None: 165 | post_data["code"] = code 166 | 167 | response = self.__do_request(post_data) 168 | 169 | json = jsond.loads(response) 170 | 171 | if json["success"]: 172 | self.__load_user_data(json["info"]) 173 | print(json["message"]) 174 | else: 175 | print(json["message"]) 176 | time.sleep(3) 177 | os._exit(1) 178 | 179 | def license(self, key, code=None, hwid=None): 180 | self.checkinit() 181 | if hwid is None: 182 | hwid = others.get_hwid() 183 | 184 | post_data = { 185 | "type": "license", 186 | "key": key, 187 | "hwid": hwid, 188 | "sessionid": self.sessionid, 189 | "name": self.name, 190 | "ownerid": self.ownerid 191 | } 192 | 193 | if code is not None: 194 | post_data["code"] = code 195 | 196 | response = self.__do_request(post_data) 197 | 198 | json = jsond.loads(response) 199 | 200 | if json["success"]: 201 | self.__load_user_data(json["info"]) 202 | print(json["message"]) 203 | else: 204 | print(json["message"]) 205 | time.sleep(3) 206 | os._exit(1) 207 | 208 | def var(self, name): 209 | self.checkinit() 210 | 211 | post_data = { 212 | "type": "var", 213 | "varid": name, 214 | "sessionid": self.sessionid, 215 | "name": self.name, 216 | "ownerid": self.ownerid 217 | } 218 | 219 | response = self.__do_request(post_data) 220 | 221 | json = jsond.loads(response) 222 | 223 | if json["success"]: 224 | return json["message"] 225 | else: 226 | print(json["message"]) 227 | time.sleep(3) 228 | os._exit(1) 229 | 230 | def getvar(self, var_name): 231 | self.checkinit() 232 | 233 | post_data = { 234 | "type": "getvar", 235 | "var": var_name, 236 | "sessionid": self.sessionid, 237 | "name": self.name, 238 | "ownerid": self.ownerid 239 | } 240 | response = self.__do_request(post_data) 241 | 242 | json = jsond.loads(response) 243 | 244 | if json["success"]: 245 | return json["response"] 246 | else: 247 | print(f"NOTE: This is commonly misunderstood. This is for user variables, not the normal variables.\nUse keyauthapp.var(\"{var_name}\") for normal variables"); 248 | print(json["message"]) 249 | time.sleep(3) 250 | os._exit(1) 251 | 252 | def setvar(self, var_name, var_data): 253 | self.checkinit() 254 | 255 | post_data = { 256 | "type": "setvar", 257 | "var": var_name, 258 | "data": var_data, 259 | "sessionid": self.sessionid, 260 | "name": self.name, 261 | "ownerid": self.ownerid 262 | } 263 | response = self.__do_request(post_data) 264 | 265 | json = jsond.loads(response) 266 | 267 | if json["success"]: 268 | return True 269 | else: 270 | print(json["message"]) 271 | time.sleep(3) 272 | os._exit(1) 273 | 274 | def ban(self): 275 | self.checkinit() 276 | 277 | post_data = { 278 | "type": "ban", 279 | "sessionid": self.sessionid, 280 | "name": self.name, 281 | "ownerid": self.ownerid 282 | } 283 | response = self.__do_request(post_data) 284 | 285 | json = jsond.loads(response) 286 | 287 | if json["success"]: 288 | return True 289 | else: 290 | print(json["message"]) 291 | time.sleep(3) 292 | os._exit(1) 293 | 294 | def file(self, fileid): 295 | self.checkinit() 296 | 297 | post_data = { 298 | "type": "file", 299 | "fileid": fileid, 300 | "sessionid": self.sessionid, 301 | "name": self.name, 302 | "ownerid": self.ownerid 303 | } 304 | 305 | response = self.__do_request(post_data) 306 | 307 | json = jsond.loads(response) 308 | 309 | if not json["success"]: 310 | print(json["message"]) 311 | time.sleep(3) 312 | os._exit(1) 313 | return binascii.unhexlify(json["contents"]) 314 | 315 | def webhook(self, webid, param, body = "", conttype = ""): 316 | self.checkinit() 317 | 318 | post_data = { 319 | "type": "webhook", 320 | "webid": webid, 321 | "params": param, 322 | "body": body, 323 | "conttype": conttype, 324 | "sessionid": self.sessionid, 325 | "name": self.name, 326 | "ownerid": self.ownerid 327 | } 328 | 329 | response = self.__do_request(post_data) 330 | 331 | json = jsond.loads(response) 332 | 333 | if json["success"]: 334 | return json["message"] 335 | else: 336 | print(json["message"]) 337 | time.sleep(3) 338 | os._exit(1) 339 | 340 | def check(self): 341 | self.checkinit() 342 | 343 | post_data = { 344 | "type": "check", 345 | "sessionid": self.sessionid, 346 | "name": self.name, 347 | "ownerid": self.ownerid 348 | } 349 | response = self.__do_request(post_data) 350 | 351 | json = jsond.loads(response) 352 | if json["success"]: 353 | return True 354 | else: 355 | return False 356 | 357 | def checkblacklist(self): 358 | self.checkinit() 359 | hwid = others.get_hwid() 360 | 361 | post_data = { 362 | "type": "checkblacklist", 363 | "hwid": hwid, 364 | "sessionid": self.sessionid, 365 | "name": self.name, 366 | "ownerid": self.ownerid 367 | } 368 | response = self.__do_request(post_data) 369 | 370 | json = jsond.loads(response) 371 | if json["success"]: 372 | return True 373 | else: 374 | return False 375 | 376 | def log(self, message): 377 | self.checkinit() 378 | 379 | post_data = { 380 | "type": "log", 381 | "pcuser": os.getenv('username'), 382 | "message": message, 383 | "sessionid": self.sessionid, 384 | "name": self.name, 385 | "ownerid": self.ownerid 386 | } 387 | 388 | self.__do_request(post_data) 389 | 390 | def fetchOnline(self): 391 | self.checkinit() 392 | 393 | post_data = { 394 | "type": "fetchOnline", 395 | "sessionid": self.sessionid, 396 | "name": self.name, 397 | "ownerid": self.ownerid 398 | } 399 | 400 | response = self.__do_request(post_data) 401 | 402 | json = jsond.loads(response) 403 | 404 | if json["success"]: 405 | if len(json["users"]) == 0: 406 | return None 407 | else: 408 | return json["users"] 409 | else: 410 | return None 411 | 412 | def fetchStats(self): 413 | self.checkinit() 414 | 415 | post_data = { 416 | "type": "fetchStats", 417 | "sessionid": self.sessionid, 418 | "name": self.name, 419 | "ownerid": self.ownerid 420 | } 421 | 422 | response = self.__do_request(post_data) 423 | 424 | json = jsond.loads(response) 425 | 426 | if json["success"]: 427 | self.__load_app_data(json["appinfo"]) 428 | 429 | def chatGet(self, channel): 430 | self.checkinit() 431 | 432 | post_data = { 433 | "type": "chatget", 434 | "channel": channel, 435 | "sessionid": self.sessionid, 436 | "name": self.name, 437 | "ownerid": self.ownerid 438 | } 439 | 440 | response = self.__do_request(post_data) 441 | 442 | json = jsond.loads(response) 443 | 444 | if json["success"]: 445 | return json["messages"] 446 | else: 447 | return None 448 | 449 | def chatSend(self, message, channel): 450 | self.checkinit() 451 | 452 | post_data = { 453 | "type": "chatsend", 454 | "message": message, 455 | "channel": channel, 456 | "sessionid": self.sessionid, 457 | "name": self.name, 458 | "ownerid": self.ownerid 459 | } 460 | 461 | response = self.__do_request(post_data) 462 | 463 | json = jsond.loads(response) 464 | 465 | if json["success"]: 466 | return True 467 | else: 468 | return False 469 | 470 | def checkinit(self): 471 | if not self.initialized: 472 | print("Initialize first, in order to use the functions") 473 | time.sleep(3) 474 | os._exit(1) 475 | 476 | def changeUsername(self, username): 477 | self.checkinit() 478 | 479 | post_data = { 480 | "type": "changeUsername", 481 | "newUsername": username, 482 | "sessionid": self.sessionid, 483 | "name": self.name, 484 | "ownerid": self.ownerid 485 | } 486 | 487 | response = self.__do_request(post_data) 488 | 489 | json = jsond.loads(response) 490 | 491 | if json["success"]: 492 | print("Successfully changed username") 493 | else: 494 | print(json["message"]) 495 | time.sleep(3) 496 | os._exit(1) 497 | 498 | def logout(self): 499 | self.checkinit() 500 | 501 | post_data = { 502 | "type": "logout", 503 | "sessionid": self.sessionid, 504 | "name": self.name, 505 | "ownerid": self.ownerid 506 | } 507 | 508 | response = self.__do_request(post_data) 509 | 510 | json = jsond.loads(response) 511 | 512 | if json["success"]: 513 | print("Successfully logged out") 514 | time.sleep(3) 515 | os._exit(1) 516 | else: 517 | print(json["message"]) 518 | time.sleep(3) 519 | os._exit(1) 520 | 521 | def enable2fa(self, code=None): 522 | self.checkinit() 523 | 524 | post_data = { 525 | "type": "2faenable", 526 | "sessionid": self.sessionid, 527 | "name": self.name, 528 | "ownerid": self.ownerid, 529 | "code": code 530 | } 531 | 532 | response = self.__do_request(post_data) 533 | 534 | json = jsond.loads(response) 535 | 536 | if json["success"]: 537 | if code is None: 538 | # First request: Display the 2FA secret code 539 | print(f"Your 2FA secret code is: {json['2fa']['secret_code']}") 540 | qr_code = json['2fa']['QRCode'] 541 | self.display_qr_code(qr_code) 542 | code_input = input("Enter the 6 digit 2fa code to enable 2fa: ") 543 | self.enable2fa(code_input); 544 | else: 545 | # Second request: Confirm successful 2FA activation 546 | print("2FA has been successfully enabled!") 547 | time.sleep(3) 548 | else: 549 | print(f"Error: {json['message']}") 550 | time.sleep(3) 551 | os._exit(1) 552 | 553 | def disable2fa(self, code=None): 554 | self.checkinit() 555 | 556 | code = input("Enter the 6 digit 2fa code to disable 2fa: ") 557 | 558 | post_data = { 559 | "type": "2fadisable", 560 | "sessionid": self.sessionid, 561 | "name": self.name, 562 | "ownerid": self.ownerid, 563 | "code": code 564 | } 565 | 566 | response = self.__do_request(post_data) 567 | 568 | json = jsond.loads(response) 569 | 570 | print(json['message']) 571 | time.sleep(3) 572 | 573 | 574 | def display_qr_code(self, qr_code_url): 575 | # Generate QR code image 576 | qr = qrcode.QRCode( 577 | version=1, 578 | error_correction=qrcode.constants.ERROR_CORRECT_L, 579 | box_size=10, 580 | border=4, 581 | ) 582 | 583 | # Add the QR code URL data 584 | qr.add_data(qr_code_url) 585 | qr.make(fit=True) 586 | 587 | # Create an image from the QR code 588 | img = qr.make_image(fill='black', back_color='white') 589 | 590 | # Display the QR code image 591 | img.show() 592 | 593 | def __do_request(self, post_data): 594 | try: 595 | response = requests.post( 596 | "https://keyauth.win/api/1.3/", data=post_data, timeout=10 597 | ) 598 | 599 | if post_data["type"] == "log" or post_data["type"] == "file" or post_data["type"] == "2faenable" or post_data["type"] == "2fadisable": 600 | return response.text 601 | 602 | # Get the signature and timestamp from the headers 603 | signature = response.headers.get("x-signature-ed25519") 604 | timestamp = response.headers.get("x-signature-timestamp") 605 | 606 | if not signature or not timestamp: 607 | print("Missing headers for signature verification.") 608 | time.sleep(3) 609 | os._exit(1) 610 | 611 | server_time = datetime.fromtimestamp(int(timestamp), timezone.utc) 612 | current_time = datetime.now(timezone.utc) 613 | 614 | #print(f"Server Timestamp (UTC seconds): {timestamp}") 615 | #print(f"Server Time (UTC seconds): {server_time.timestamp()}") 616 | #print(f"Current Time (UTC seconds): {current_time.timestamp()}") 617 | 618 | buffer_seconds = 5 619 | time_difference = current_time - server_time 620 | 621 | if time_difference > timedelta(seconds=20 + buffer_seconds): 622 | print("Timestamp is too old (exceeded 20 seconds + buffer).") 623 | time.sleep(3) 624 | os._exit(1) 625 | 626 | if not verify_key(response.text.encode('utf-8'), signature, timestamp, '5586b4bc69c7a4b487e4563a4cd96afd39140f919bd31cea7d1c6a1e8439422b'): 627 | print("Signature checksum failed. Request was tampered with or session ended most likely.") 628 | time.sleep(3) 629 | os._exit(1) 630 | 631 | return response.text 632 | 633 | except requests.exceptions.Timeout: 634 | print("Request timed out. Server is probably down/slow at the moment") 635 | 636 | 637 | class application_data_class: 638 | numUsers = numKeys = app_ver = customer_panel = onlineUsers = "" 639 | 640 | class user_data_class: 641 | username = ip = hwid = expires = createdate = lastlogin = subscription = subscriptions = "" 642 | 643 | user_data = user_data_class() 644 | app_data = application_data_class() 645 | 646 | def __load_app_data(self, data): 647 | self.app_data.numUsers = data["numUsers"] 648 | self.app_data.numKeys = data["numKeys"] 649 | self.app_data.app_ver = data["version"] 650 | self.app_data.customer_panel = data["customerPanelLink"] 651 | self.app_data.onlineUsers = data["numOnlineUsers"] 652 | 653 | def __load_user_data(self, data): 654 | self.user_data.username = data["username"] 655 | self.user_data.ip = data["ip"] 656 | self.user_data.hwid = data["hwid"] or "N/A" 657 | self.user_data.expires = data["subscriptions"][0]["expiry"] 658 | self.user_data.createdate = data["createdate"] 659 | self.user_data.lastlogin = data["lastlogin"] 660 | self.user_data.subscription = data["subscriptions"][0]["subscription"] 661 | self.user_data.subscriptions = data["subscriptions"] 662 | 663 | 664 | class others: 665 | @staticmethod 666 | def get_hwid(): 667 | if platform.system() == "Linux": 668 | with open("/etc/machine-id") as f: 669 | hwid = f.read() 670 | return hwid 671 | elif platform.system() == 'Windows': 672 | winuser = os.getlogin() 673 | sid = win32security.LookupAccountName(None, winuser)[0] # You can also use WMIC (better than SID, some users had problems with WMIC) 674 | hwid = win32security.ConvertSidToStringSid(sid) 675 | return hwid 676 | ''' 677 | cmd = subprocess.Popen( 678 | "wmic useraccount where name='%username%' get sid", 679 | stdout=subprocess.PIPE, 680 | shell=True, 681 | ) 682 | 683 | (suppost_sid, error) = cmd.communicate() 684 | 685 | suppost_sid = suppost_sid.split(b"\n")[1].strip() 686 | 687 | return suppost_sid.decode() 688 | 689 | ^^ HOW TO DO IT USING WMIC 690 | ''' 691 | elif platform.system() == 'Darwin': 692 | output = subprocess.Popen("ioreg -l | grep IOPlatformSerialNumber", stdout=subprocess.PIPE, shell=True).communicate()[0] 693 | serial = output.decode().split('=', 1)[1].replace(' ', '') 694 | hwid = serial[1:-2] 695 | return hwid -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | ''' 2 | KeyAuth.cc Python Example 3 | 4 | Go to https://keyauth.cc/app/ and click the Python tab. Copy that code and replace the existing keyauthapp instance in this file. 5 | 6 | If you get an error saying it can't find module KeyAuth, try following this https://github.com/KeyAuth/KeyAuth-Python-Example#how-to-compile 7 | 8 | If that doesn't work for you, you can paste the contents of KeyAuth.py ABOVE this comment and then remove the "from keyauth import api" and that should work too. 9 | 10 | READ HERE TO LEARN ABOUT KEYAUTH FUNCTIONS https://github.com/KeyAuth/KeyAuth-Python-Example#keyauthapp-instance-definition 11 | ''' 12 | from keyauth import api 13 | 14 | import sys 15 | import time 16 | import platform 17 | import os 18 | import hashlib 19 | from time import sleep 20 | from datetime import datetime, UTC 21 | 22 | # import json as jsond 23 | # ^^ only for auto login/json writing/reading 24 | 25 | # watch setup video if you need help https://www.youtube.com/watch?v=L2eAQOmuUiA 26 | 27 | def clear(): 28 | if platform.system() == 'Windows': 29 | os.system('cls & title Python Example') # clear console, change title 30 | elif platform.system() == 'Linux': 31 | os.system('clear') # Clear the terminal 32 | sys.stdout.write("\033]0;Python Example\007") # Set terminal title 33 | sys.stdout.flush() 34 | elif platform.system() == 'Darwin': 35 | os.system("clear && printf '\033[3J'") # Clear terminal and scrollback 36 | os.system('echo -n -e "\033]0;Python Example\007"') # Set terminal title 37 | 38 | print("Initializing") 39 | 40 | 41 | def getchecksum(): 42 | md5_hash = hashlib.md5() 43 | file = open(''.join(sys.argv), "rb") 44 | md5_hash.update(file.read()) 45 | digest = md5_hash.hexdigest() 46 | return digest 47 | 48 | 49 | keyauthapp = api( 50 | name = "", # App name 51 | ownerid = "", # Account ID 52 | version = "", # Application version. Used for automatic downloads see video here https://www.youtube.com/watch?v=kW195PLCBKs 53 | hash_to_check = getchecksum() 54 | ) 55 | 56 | def answer(): 57 | try: 58 | print("""1.Login 59 | 2.Register 60 | 3.Upgrade 61 | 4.License Key Only 62 | """) 63 | ans = input("Select Option: ") 64 | if ans == "1": 65 | user = input('Provide username: ') 66 | password = input('Provide password: ') 67 | code = input('Enter 2fa code: (not using 2fa? Just press enter)') 68 | keyauthapp.login(user, password, code) 69 | elif ans == "2": 70 | user = input('Provide username: ') 71 | password = input('Provide password: ') 72 | license = input('Provide License: ') 73 | keyauthapp.register(user, password, license) 74 | elif ans == "3": 75 | user = input('Provide username: ') 76 | license = input('Provide License: ') 77 | keyauthapp.upgrade(user, license) 78 | elif ans == "4": 79 | key = input('Enter your license: ') 80 | code = input('Enter 2fa code: (not using 2fa? Just press enter)') 81 | keyauthapp.license(key, code) 82 | else: 83 | print("\nInvalid option") 84 | sleep(1) 85 | clear() 86 | answer() 87 | except KeyboardInterrupt: 88 | os._exit(1) 89 | 90 | 91 | answer() 92 | 93 | '''try: 94 | if os.path.isfile('auth.json'): #Checking if the auth file exist 95 | if jsond.load(open("auth.json"))["authusername"] == "": #Checks if the authusername is empty or not 96 | print(""" 97 | 1. Login 98 | 2. Register 99 | """) 100 | ans=input("Select Option: ") #Skipping auto-login bc auth file is empty 101 | if ans=="1": 102 | user = input('Provide username: ') 103 | password = input('Provide password: ') 104 | keyauthapp.login(user,password) 105 | authfile = jsond.load(open("auth.json")) 106 | authfile["authusername"] = user 107 | authfile["authpassword"] = password 108 | jsond.dump(authfile, open('auth.json', 'w'), sort_keys=False, indent=4) 109 | elif ans=="2": 110 | user = input('Provide username: ') 111 | password = input('Provide password: ') 112 | license = input('Provide License: ') 113 | keyauthapp.register(user,password,license) 114 | authfile = jsond.load(open("auth.json")) 115 | authfile["authusername"] = user 116 | authfile["authpassword"] = password 117 | jsond.dump(authfile, open('auth.json', 'w'), sort_keys=False, indent=4) 118 | else: 119 | print("\nNot Valid Option") 120 | os._exit(1) 121 | else: 122 | try: #2. Auto login 123 | with open('auth.json', 'r') as f: 124 | authfile = jsond.load(f) 125 | authuser = authfile.get('authusername') 126 | authpass = authfile.get('authpassword') 127 | keyauthapp.login(authuser,authpass) 128 | except Exception as e: #Error stuff 129 | print(e) 130 | else: #Creating auth file bc its missing 131 | try: 132 | f = open("auth.json", "a") #Writing content 133 | f.write("""{ 134 | "authusername": "", 135 | "authpassword": "" 136 | }""") 137 | f.close() 138 | print (""" 139 | 1. Login 140 | 2. Register 141 | """)#Again skipping auto-login bc the file is empty/missing 142 | ans=input("Select Option: ") 143 | if ans=="1": 144 | user = input('Provide username: ') 145 | password = input('Provide password: ') 146 | keyauthapp.login(user,password) 147 | authfile = jsond.load(open("auth.json")) 148 | authfile["authusername"] = user 149 | authfile["authpassword"] = password 150 | jsond.dump(authfile, open('auth.json', 'w'), sort_keys=False, indent=4) 151 | elif ans=="2": 152 | user = input('Provide username: ') 153 | password = input('Provide password: ') 154 | license = input('Provide License: ') 155 | keyauthapp.register(user,password,license) 156 | authfile = jsond.load(open("auth.json")) 157 | authfile["authusername"] = user 158 | authfile["authpassword"] = password 159 | jsond.dump(authfile, open('auth.json', 'w'), sort_keys=False, indent=4) 160 | else: 161 | print("\nNot Valid Option") 162 | os._exit(1) 163 | except Exception as e: #Error stuff 164 | print(e) 165 | os._exit(1) 166 | except Exception as e: #Error stuff 167 | print(e) 168 | os._exit(1)''' 169 | 170 | keyauthapp.fetchStats() 171 | # Display Application Data 172 | print("\nApplication data: ") 173 | print("App Version: " + keyauthapp.app_data.app_ver) 174 | print("Customer Panel Link: " + keyauthapp.app_data.customer_panel) 175 | print("Number of Keys: " + keyauthapp.app_data.numKeys) 176 | print("Number of Users: " + keyauthapp.app_data.numUsers) 177 | print("Online Users: " + keyauthapp.app_data.onlineUsers) 178 | 179 | # Display User Data 180 | print("\nUser data: ") 181 | print("Username: " + keyauthapp.user_data.username) 182 | print("IP address: " + keyauthapp.user_data.ip) 183 | print("Hardware-Id: " + keyauthapp.user_data.hwid) 184 | 185 | subs = keyauthapp.user_data.subscriptions # Get all Subscription names, expiry, and timeleft 186 | for i in range(len(subs)): 187 | sub = subs[i]["subscription"] # Subscription from every Sub 188 | expiry = datetime.fromtimestamp(int(subs[i]["expiry"]), UTC).strftime( 189 | '%Y-%m-%d %H:%M:%S') # Expiry date from every Sub 190 | timeleft = subs[i]["timeleft"] # Timeleft from every Sub 191 | 192 | print(f"[{i + 1} / {len(subs)}] | Subscription: {sub} - Expiry: {expiry} - Timeleft: {timeleft}") 193 | 194 | print("Created at: " + datetime.fromtimestamp(int(keyauthapp.user_data.createdate), UTC).strftime('%Y-%m-%d %H:%M:%S')) 195 | print("Last login at: " + datetime.fromtimestamp(int(keyauthapp.user_data.lastlogin), UTC).strftime('%Y-%m-%d %H:%M:%S')) 196 | print("Expires at: " + datetime.fromtimestamp(int(keyauthapp.user_data.expires), UTC).strftime('%Y-%m-%d %H:%M:%S')) 197 | 198 | # Two Factor Authentication 199 | print("\nTwo Factor Authentication:") 200 | print("1. Enable 2FA") 201 | print("2. Disable 2FA") 202 | 203 | tfaans = input("Select Option: ") 204 | if tfaans == "1": 205 | keyauthapp.enable2fa() # You only need to call this once as it's called in the API file. 206 | elif tfaans == "2": 207 | keyauthapp.disable2fa() # You only need to call this once as it's called in the API file, and should ideally only need to be called once anyways. 208 | else: 209 | print("\nInvalid Option") 210 | 211 | print("\nExiting in five seconds..") 212 | sleep(5) 213 | os._exit(1) 214 | -------------------------------------------------------------------------------- /other-examples/README.md: -------------------------------------------------------------------------------- 1 | # Other-Examples 2 | KeyAuth Python Examples 3 | 4 | **merged_example.py** 5 | 6 | Yes title says everything. This file contains the `keyauth.py` and `main.py` from https://github.com/KeyAuth/KeyAuth-Python-Example 7 | 8 | A few people did not know how to merge the files, so I made an example. 9 | 10 | **method1.py** 11 | 12 | This file shows you how to add your program to keyauth example. 13 | 14 | All you have to do is copy and paste your code below the example, you can check it in the `method1.py` file. 15 | 16 | **method2.py** 17 | 18 | This file shows you how to use your code if it's above the example code. 19 | 20 | - This method will only work if you call your functions after login. 21 | - **Example:** 22 | Create 1 function that will call all the other needed functions. You can also create 1 function and put everything in it. This is all your choice, method 1 would be a better idea. 23 | - This can be exploited with Python code injection, for example injecting a code that will call the function before login. 24 | 25 | 26 | >Created by: `Marci#1337` 27 | -------------------------------------------------------------------------------- /other-examples/merged_example.py: -------------------------------------------------------------------------------- 1 | # 1 file version 2 | 3 | import binascii # hex encoding 4 | import hashlib 5 | import json as jsond # json 6 | import os 7 | import platform # check platform 8 | import subprocess # needed for mac device 9 | import sys 10 | import time # sleep before exit 11 | from datetime import datetime 12 | from time import sleep 13 | from uuid import uuid4 # gen random guid 14 | 15 | try: 16 | if os.name == 'nt': 17 | import win32security # get sid (WIN only) 18 | import requests # https requests 19 | from Crypto.Cipher import AES 20 | from Crypto.Hash import SHA256 21 | from Crypto.Util.Padding import pad, unpad 22 | except ModuleNotFoundError: 23 | print("Exception when importing modules") 24 | print("Installing necessary modules....") 25 | if os.path.isfile("requirements.txt"): 26 | os.system("pip install -r requirements.txt") 27 | else: 28 | os.system("pip install pywin32") 29 | os.system("pip install pycryptodome") 30 | os.system("pip install requests") 31 | print("Modules installed!") 32 | time.sleep(1.5) 33 | os._exit(1) 34 | 35 | try: # Connection check 36 | s = requests.Session() # Session 37 | s.get('https://google.com') 38 | except requests.exceptions.RequestException as e: 39 | print(e) 40 | time.sleep(3) 41 | os._exit(1) 42 | 43 | 44 | class api: 45 | 46 | name = ownerid = secret = version = hash_to_check = "" 47 | 48 | def __init__(self, name, ownerid, secret, version, hash_to_check): 49 | self.name = name 50 | 51 | self.ownerid = ownerid 52 | 53 | self.secret = secret 54 | 55 | self.version = version 56 | self.hash_to_check = hash_to_check 57 | self.init() 58 | 59 | sessionid = enckey = "" 60 | initialized = False 61 | 62 | def init(self): 63 | 64 | if self.sessionid != "": 65 | print("You've already initialized!") 66 | time.sleep(2) 67 | os._exit(1) 68 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 69 | 70 | self.enckey = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 71 | 72 | post_data = { 73 | "type": binascii.hexlify(("init").encode()), 74 | "ver": encryption.encrypt(self.version, self.secret, init_iv), 75 | "hash": self.hash_to_check, 76 | "enckey": encryption.encrypt(self.enckey, self.secret, init_iv), 77 | "name": binascii.hexlify(self.name.encode()), 78 | "ownerid": binascii.hexlify(self.ownerid.encode()), 79 | "init_iv": init_iv 80 | } 81 | 82 | response = self.__do_request(post_data) 83 | 84 | if response == "KeyAuth_Invalid": 85 | print("The application doesn't exist") 86 | os._exit(1) 87 | 88 | response = encryption.decrypt(response, self.secret, init_iv) 89 | json = jsond.loads(response) 90 | 91 | if json["message"] == "invalidver": 92 | if json["download"] != "": 93 | print("New Version Available") 94 | download_link = json["download"] 95 | os.system(f"start {download_link}") 96 | os._exit(1) 97 | else: 98 | print("Invalid Version, Contact owner to add download link to latest app version") 99 | os._exit(1) 100 | 101 | if not json["success"]: 102 | print(json["message"]) 103 | os._exit(1) 104 | 105 | self.sessionid = json["sessionid"] 106 | self.initialized = True 107 | self.__load_app_data(json["appinfo"]) 108 | 109 | def register(self, user, password, license, hwid=None): 110 | self.checkinit() 111 | if hwid is None: 112 | hwid = others.get_hwid() 113 | 114 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 115 | 116 | post_data = { 117 | "type": binascii.hexlify(("register").encode()), 118 | "username": encryption.encrypt(user, self.enckey, init_iv), 119 | "pass": encryption.encrypt(password, self.enckey, init_iv), 120 | "key": encryption.encrypt(license, self.enckey, init_iv), 121 | "hwid": encryption.encrypt(hwid, self.enckey, init_iv), 122 | "sessionid": binascii.hexlify(self.sessionid.encode()), 123 | "name": binascii.hexlify(self.name.encode()), 124 | "ownerid": binascii.hexlify(self.ownerid.encode()), 125 | "init_iv": init_iv 126 | } 127 | 128 | response = self.__do_request(post_data) 129 | response = encryption.decrypt(response, self.enckey, init_iv) 130 | json = jsond.loads(response) 131 | 132 | if json["success"]: 133 | print("successfully registered") 134 | self.__load_user_data(json["info"]) 135 | else: 136 | print(json["message"]) 137 | os._exit(1) 138 | 139 | def upgrade(self, user, license): 140 | self.checkinit() 141 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 142 | 143 | post_data = { 144 | "type": binascii.hexlify(("upgrade").encode()), 145 | "username": encryption.encrypt(user, self.enckey, init_iv), 146 | "key": encryption.encrypt(license, self.enckey, init_iv), 147 | "sessionid": binascii.hexlify(self.sessionid.encode()), 148 | "name": binascii.hexlify(self.name.encode()), 149 | "ownerid": binascii.hexlify(self.ownerid.encode()), 150 | "init_iv": init_iv 151 | } 152 | 153 | response = self.__do_request(post_data) 154 | 155 | response = encryption.decrypt(response, self.enckey, init_iv) 156 | 157 | json = jsond.loads(response) 158 | 159 | if json["success"]: 160 | print("successfully upgraded user") 161 | print("please restart program and login") 162 | time.sleep(2) 163 | os._exit(1) 164 | else: 165 | print(json["message"]) 166 | os._exit(1) 167 | 168 | def login(self, user, password, hwid=None): 169 | self.checkinit() 170 | if hwid is None: 171 | hwid = others.get_hwid() 172 | 173 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 174 | 175 | post_data = { 176 | "type": binascii.hexlify(("login").encode()), 177 | "username": encryption.encrypt(user, self.enckey, init_iv), 178 | "pass": encryption.encrypt(password, self.enckey, init_iv), 179 | "hwid": encryption.encrypt(hwid, self.enckey, init_iv), 180 | "sessionid": binascii.hexlify(self.sessionid.encode()), 181 | "name": binascii.hexlify(self.name.encode()), 182 | "ownerid": binascii.hexlify(self.ownerid.encode()), 183 | "init_iv": init_iv 184 | } 185 | 186 | response = self.__do_request(post_data) 187 | 188 | response = encryption.decrypt(response, self.enckey, init_iv) 189 | 190 | json = jsond.loads(response) 191 | 192 | if json["success"]: 193 | self.__load_user_data(json["info"]) 194 | print("successfully logged in") 195 | else: 196 | print(json["message"]) 197 | os._exit(1) 198 | 199 | def license(self, key, hwid=None): 200 | self.checkinit() 201 | if hwid is None: 202 | hwid = others.get_hwid() 203 | 204 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 205 | 206 | post_data = { 207 | "type": binascii.hexlify(("license").encode()), 208 | "key": encryption.encrypt(key, self.enckey, init_iv), 209 | "hwid": encryption.encrypt(hwid, self.enckey, init_iv), 210 | "sessionid": binascii.hexlify(self.sessionid.encode()), 211 | "name": binascii.hexlify(self.name.encode()), 212 | "ownerid": binascii.hexlify(self.ownerid.encode()), 213 | "init_iv": init_iv 214 | } 215 | 216 | response = self.__do_request(post_data) 217 | response = encryption.decrypt(response, self.enckey, init_iv) 218 | 219 | json = jsond.loads(response) 220 | 221 | if json["success"]: 222 | self.__load_user_data(json["info"]) 223 | print("successfully logged into license") 224 | else: 225 | print(json["message"]) 226 | os._exit(1) 227 | 228 | def var(self, name): 229 | self.checkinit() 230 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 231 | 232 | post_data = { 233 | "type": binascii.hexlify(("var").encode()), 234 | "varid": encryption.encrypt(name, self.enckey, init_iv), 235 | "sessionid": binascii.hexlify(self.sessionid.encode()), 236 | "name": binascii.hexlify(self.name.encode()), 237 | "ownerid": binascii.hexlify(self.ownerid.encode()), 238 | "init_iv": init_iv 239 | } 240 | 241 | response = self.__do_request(post_data) 242 | 243 | response = encryption.decrypt(response, self.enckey, init_iv) 244 | 245 | json = jsond.loads(response) 246 | 247 | if json["success"]: 248 | return json["message"] 249 | else: 250 | print(json["message"]) 251 | time.sleep(5) 252 | os._exit(1) 253 | 254 | def getvar(self, var_name): 255 | self.checkinit() 256 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 257 | 258 | post_data = { 259 | "type": binascii.hexlify(("getvar").encode()), 260 | "var": encryption.encrypt(var_name, self.enckey, init_iv), 261 | "sessionid": binascii.hexlify(self.sessionid.encode()), 262 | "name": binascii.hexlify(self.name.encode()), 263 | "ownerid": binascii.hexlify(self.ownerid.encode()), 264 | "init_iv": init_iv 265 | } 266 | response = self.__do_request(post_data) 267 | response = encryption.decrypt(response, self.enckey, init_iv) 268 | json = jsond.loads(response) 269 | 270 | if json["success"]: 271 | return json["response"] 272 | else: 273 | print(json["message"]) 274 | time.sleep(5) 275 | os._exit(1) 276 | 277 | def setvar(self, var_name, var_data): 278 | self.checkinit() 279 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 280 | post_data = { 281 | "type": binascii.hexlify(("setvar").encode()), 282 | "var": encryption.encrypt(var_name, self.enckey, init_iv), 283 | "data": encryption.encrypt(var_data, self.enckey, init_iv), 284 | "sessionid": binascii.hexlify(self.sessionid.encode()), 285 | "name": binascii.hexlify(self.name.encode()), 286 | "ownerid": binascii.hexlify(self.ownerid.encode()), 287 | "init_iv": init_iv 288 | } 289 | response = self.__do_request(post_data) 290 | response = encryption.decrypt(response, self.enckey, init_iv) 291 | json = jsond.loads(response) 292 | 293 | if json["success"]: 294 | return True 295 | else: 296 | print(json["message"]) 297 | time.sleep(5) 298 | os._exit(1) 299 | 300 | def ban(self): 301 | self.checkinit() 302 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 303 | post_data = { 304 | "type": binascii.hexlify(("ban").encode()), 305 | "sessionid": binascii.hexlify(self.sessionid.encode()), 306 | "name": binascii.hexlify(self.name.encode()), 307 | "ownerid": binascii.hexlify(self.ownerid.encode()), 308 | "init_iv": init_iv 309 | } 310 | response = self.__do_request(post_data) 311 | response = encryption.decrypt(response, self.enckey, init_iv) 312 | json = jsond.loads(response) 313 | 314 | if json["success"]: 315 | return True 316 | else: 317 | print(json["message"]) 318 | time.sleep(5) 319 | os._exit(1) 320 | 321 | def file(self, fileid): 322 | self.checkinit() 323 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 324 | 325 | post_data = { 326 | "type": binascii.hexlify(("file").encode()), 327 | "fileid": encryption.encrypt(fileid, self.enckey, init_iv), 328 | "sessionid": binascii.hexlify(self.sessionid.encode()), 329 | "name": binascii.hexlify(self.name.encode()), 330 | "ownerid": binascii.hexlify(self.ownerid.encode()), 331 | "init_iv": init_iv 332 | } 333 | 334 | response = self.__do_request(post_data) 335 | 336 | response = encryption.decrypt(response, self.enckey, init_iv) 337 | 338 | json = jsond.loads(response) 339 | 340 | if not json["success"]: 341 | print(json["message"]) 342 | time.sleep(5) 343 | os._exit(1) 344 | return binascii.unhexlify(json["contents"]) 345 | 346 | def webhook(self, webid, param, body = "", conttype = ""): 347 | self.checkinit() 348 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 349 | 350 | post_data = { 351 | "type": binascii.hexlify(("webhook").encode()), 352 | "webid": encryption.encrypt(webid, self.enckey, init_iv), 353 | "params": encryption.encrypt(param, self.enckey, init_iv), 354 | "body": encryption.encrypt(body, self.enckey, init_iv), 355 | "conttype": encryption.encrypt(conttype, self.enckey, init_iv), 356 | "sessionid": binascii.hexlify(self.sessionid.encode()), 357 | "name": binascii.hexlify(self.name.encode()), 358 | "ownerid": binascii.hexlify(self.ownerid.encode()), 359 | "init_iv": init_iv 360 | } 361 | 362 | response = self.__do_request(post_data) 363 | 364 | response = encryption.decrypt(response, self.enckey, init_iv) 365 | json = jsond.loads(response) 366 | 367 | if json["success"]: 368 | return json["message"] 369 | else: 370 | print(json["message"]) 371 | time.sleep(5) 372 | os._exit(1) 373 | 374 | def check(self): 375 | self.checkinit() 376 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 377 | post_data = { 378 | "type": binascii.hexlify(("check").encode()), 379 | "sessionid": binascii.hexlify(self.sessionid.encode()), 380 | "name": binascii.hexlify(self.name.encode()), 381 | "ownerid": binascii.hexlify(self.ownerid.encode()), 382 | "init_iv": init_iv 383 | } 384 | response = self.__do_request(post_data) 385 | 386 | response = encryption.decrypt(response, self.enckey, init_iv) 387 | json = jsond.loads(response) 388 | if json["success"]: 389 | return True 390 | else: 391 | return False 392 | 393 | def checkblacklist(self): 394 | self.checkinit() 395 | hwid = others.get_hwid() 396 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 397 | post_data = { 398 | "type": binascii.hexlify(("checkblacklist").encode()), 399 | "hwid": encryption.encrypt(hwid, self.enckey, init_iv), 400 | "sessionid": binascii.hexlify(self.sessionid.encode()), 401 | "name": binascii.hexlify(self.name.encode()), 402 | "ownerid": binascii.hexlify(self.ownerid.encode()), 403 | "init_iv": init_iv 404 | } 405 | response = self.__do_request(post_data) 406 | 407 | response = encryption.decrypt(response, self.enckey, init_iv) 408 | json = jsond.loads(response) 409 | if json["success"]: 410 | return True 411 | else: 412 | return False 413 | 414 | def log(self, message): 415 | self.checkinit() 416 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 417 | 418 | post_data = { 419 | "type": binascii.hexlify(("log").encode()), 420 | "pcuser": encryption.encrypt(os.getenv('username'), self.enckey, init_iv), 421 | "message": encryption.encrypt(message, self.enckey, init_iv), 422 | "sessionid": binascii.hexlify(self.sessionid.encode()), 423 | "name": binascii.hexlify(self.name.encode()), 424 | "ownerid": binascii.hexlify(self.ownerid.encode()), 425 | "init_iv": init_iv 426 | } 427 | 428 | self.__do_request(post_data) 429 | 430 | def fetchOnline(self): 431 | self.checkinit() 432 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 433 | 434 | post_data = { 435 | "type": binascii.hexlify(("fetchOnline").encode()), 436 | "sessionid": binascii.hexlify(self.sessionid.encode()), 437 | "name": binascii.hexlify(self.name.encode()), 438 | "ownerid": binascii.hexlify(self.ownerid.encode()), 439 | "init_iv": init_iv 440 | } 441 | 442 | response = self.__do_request(post_data) 443 | response = encryption.decrypt(response, self.enckey, init_iv) 444 | 445 | json = jsond.loads(response) 446 | 447 | if json["success"]: 448 | if len(json["users"]) == 0: 449 | return None # THIS IS ISSUE ON KEYAUTH SERVER SIDE 6.8.2022, so it will return none if it is not an array. 450 | else: 451 | return json["users"] 452 | else: 453 | return None 454 | 455 | def chatGet(self, channel): 456 | self.checkinit() 457 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 458 | 459 | post_data = { 460 | "type": binascii.hexlify(("chatget").encode()), 461 | "channel": encryption.encrypt(channel, self.enckey, init_iv), 462 | "sessionid": binascii.hexlify(self.sessionid.encode()), 463 | "name": binascii.hexlify(self.name.encode()), 464 | "ownerid": binascii.hexlify(self.ownerid.encode()), 465 | "init_iv": init_iv 466 | } 467 | 468 | response = self.__do_request(post_data) 469 | response = encryption.decrypt(response, self.enckey, init_iv) 470 | 471 | json = jsond.loads(response) 472 | 473 | if json["success"]: 474 | return json["messages"] 475 | else: 476 | return None 477 | 478 | def chatSend(self, message, channel): 479 | self.checkinit() 480 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 481 | 482 | post_data = { 483 | "type": binascii.hexlify(("chatsend").encode()), 484 | "message": encryption.encrypt(message, self.enckey, init_iv), 485 | "channel": encryption.encrypt(channel, self.enckey, init_iv), 486 | "sessionid": binascii.hexlify(self.sessionid.encode()), 487 | "name": binascii.hexlify(self.name.encode()), 488 | "ownerid": binascii.hexlify(self.ownerid.encode()), 489 | "init_iv": init_iv 490 | } 491 | 492 | response = self.__do_request(post_data) 493 | response = encryption.decrypt(response, self.enckey, init_iv) 494 | 495 | json = jsond.loads(response) 496 | 497 | if json["success"]: 498 | return True 499 | else: 500 | return False 501 | 502 | def checkinit(self): 503 | if not self.initialized: 504 | print("Initialize first, in order to use the functions") 505 | time.sleep(2) 506 | os._exit(1) 507 | 508 | def __do_request(self, post_data): 509 | try: 510 | rq_out = s.post( 511 | "https://keyauth.win/api/1.0/", data=post_data, timeout=30 512 | ) 513 | return rq_out.text 514 | except requests.exceptions.Timeout: 515 | print("Request timed out") 516 | 517 | class application_data_class: 518 | numUsers = numKeys = app_ver = customer_panel = onlineUsers = "" 519 | # region user_data 520 | 521 | class user_data_class: 522 | username = ip = hwid = expires = createdate = lastlogin = subscription = subscriptions = "" 523 | 524 | user_data = user_data_class() 525 | app_data = application_data_class() 526 | 527 | def __load_app_data(self, data): 528 | self.app_data.numUsers = data["numUsers"] 529 | self.app_data.numKeys = data["numKeys"] 530 | self.app_data.app_ver = data["version"] 531 | self.app_data.customer_panel = data["customerPanelLink"] 532 | self.app_data.onlineUsers = data["numOnlineUsers"] 533 | 534 | def __load_user_data(self, data): 535 | self.user_data.username = data["username"] 536 | self.user_data.ip = data["ip"] 537 | self.user_data.hwid = data["hwid"] 538 | self.user_data.expires = data["subscriptions"][0]["expiry"] 539 | self.user_data.createdate = data["createdate"] 540 | self.user_data.lastlogin = data["lastlogin"] 541 | self.user_data.subscription = data["subscriptions"][0]["subscription"] 542 | self.user_data.subscriptions = data["subscriptions"] 543 | 544 | 545 | class others: 546 | @staticmethod 547 | def get_hwid(): 548 | if platform.system() == "Linux": 549 | with open("/etc/machine-id") as f: 550 | hwid = f.read() 551 | return hwid 552 | elif platform.system() == 'Windows': 553 | winuser = os.getlogin() 554 | sid = win32security.LookupAccountName(None, winuser)[0] 555 | hwid = win32security.ConvertSidToStringSid(sid) 556 | return hwid 557 | elif platform.system() == 'Darwin': 558 | output = subprocess.Popen("ioreg -l | grep IOPlatformSerialNumber", stdout=subprocess.PIPE, shell=True).communicate()[0] 559 | serial = output.decode().split('=', 1)[1].replace(' ', '') 560 | hwid = serial[1:-2] 561 | return hwid 562 | 563 | 564 | 565 | class encryption: 566 | @staticmethod 567 | def encrypt_string(plain_text, key, iv): 568 | plain_text = pad(plain_text, 16) 569 | 570 | aes_instance = AES.new(key, AES.MODE_CBC, iv) 571 | 572 | raw_out = aes_instance.encrypt(plain_text) 573 | 574 | return binascii.hexlify(raw_out) 575 | 576 | @staticmethod 577 | def decrypt_string(cipher_text, key, iv): 578 | cipher_text = binascii.unhexlify(cipher_text) 579 | 580 | aes_instance = AES.new(key, AES.MODE_CBC, iv) 581 | 582 | cipher_text = aes_instance.decrypt(cipher_text) 583 | 584 | return unpad(cipher_text, 16) 585 | 586 | @staticmethod 587 | def encrypt(message, enc_key, iv): 588 | try: 589 | _key = SHA256.new(enc_key.encode()).hexdigest()[:32] 590 | 591 | _iv = SHA256.new(iv.encode()).hexdigest()[:16] 592 | 593 | return encryption.encrypt_string(message.encode(), _key.encode(), _iv.encode()).decode() 594 | except: 595 | print("Invalid Application Information. Long text is secret short text is ownerid. Name is supposed to be app name not username") 596 | os._exit(1) 597 | 598 | @staticmethod 599 | def decrypt(message, enc_key, iv): 600 | try: 601 | _key = SHA256.new(enc_key.encode()).hexdigest()[:32] 602 | 603 | _iv = SHA256.new(iv.encode()).hexdigest()[:16] 604 | 605 | return encryption.decrypt_string(message.encode(), _key.encode(), _iv.encode()).decode() 606 | except: 607 | print("Invalid Application Information. Long text is secret short text is ownerid. Name is supposed to be app name not username") 608 | os._exit(1) 609 | 610 | 611 | # import json as jsond 612 | # ^^ only for auto login/json writing/reading 613 | 614 | # watch setup video if you need help https://www.youtube.com/watch?v=L2eAQOmuUiA 615 | 616 | if sys.version_info.minor < 10: # Python version check (Bypass Patch) 617 | print("[Security] - Python 3.10 or higher is recommended. The bypass will not work on 3.10+") 618 | print("You are using Python {}.{}".format(sys.version_info.major, sys.version_info.minor)) 619 | 620 | if platform.system() == 'Windows': 621 | os.system('cls & title Python Example') # clear console, change title 622 | elif platform.system() == 'Linux': 623 | os.system('clear') # clear console 624 | sys.stdout.write("\x1b]0;Python Example\x07") # change title 625 | elif platform.system() == 'Darwin': 626 | os.system("clear && printf '\e[3J'") # clear console 627 | os.system('''echo - n - e "\033]0;Python Example\007"''') # change title 628 | 629 | print("Initializing") 630 | 631 | 632 | def getchecksum(): 633 | md5_hash = hashlib.md5() 634 | file = open(''.join(sys.argv), "rb") 635 | md5_hash.update(file.read()) 636 | digest = md5_hash.hexdigest() 637 | return digest 638 | 639 | 640 | keyauthapp = api( 641 | name = "", #App name (Manage Applications --> Application name) 642 | ownerid = "", #Owner ID (Account-Settings --> OwnerID) 643 | secret = "", #App secret(Manage Applications --> App credentials code) 644 | version = "1.0", 645 | hash_to_check = getchecksum() 646 | ) 647 | 648 | print(f""" 649 | App data: 650 | Number of users: {keyauthapp.app_data.numUsers} 651 | Number of online users: {keyauthapp.app_data.onlineUsers} 652 | Number of keys: {keyauthapp.app_data.numKeys} 653 | Application Version: {keyauthapp.app_data.app_ver} 654 | Customer panel link: {keyauthapp.app_data.customer_panel} 655 | """) 656 | print(f"Current Session Validation Status: {keyauthapp.check()}") 657 | print(f"Blacklisted? : {keyauthapp.checkblacklist()}") # check if blacklisted, you can edit this and make it exit the program if blacklisted 658 | 659 | 660 | def answer(): 661 | try: 662 | print(""" 663 | 1.Login 664 | 2.Register 665 | 3.Upgrade 666 | 4.License Key Only 667 | """) 668 | ans = input("Select Option: ") 669 | if ans == "1": 670 | user = input('Provide username: ') 671 | password = input('Provide password: ') 672 | keyauthapp.login(user, password) 673 | elif ans == "2": 674 | user = input('Provide username: ') 675 | password = input('Provide password: ') 676 | license = input('Provide License: ') 677 | keyauthapp.register(user, password, license) 678 | elif ans == "3": 679 | user = input('Provide username: ') 680 | license = input('Provide License: ') 681 | keyauthapp.upgrade(user, license) 682 | elif ans == "4": 683 | key = input('Enter your license: ') 684 | keyauthapp.license(key) 685 | else: 686 | print("\nNot Valid Option") 687 | time.sleep(1) 688 | os.system('cls') 689 | answer() 690 | except KeyboardInterrupt: 691 | os._exit(1) 692 | 693 | 694 | answer() 695 | 696 | # region Extra Functions 697 | 698 | # * Download Files form the server to your computer using the download function in the api class 699 | # bytes = keyauthapp.file("FILEID") 700 | # f = open("example.exe", "wb") 701 | # f.write(bytes) 702 | # f.close() 703 | 704 | 705 | # * Set up user variable 706 | # keyauthapp.setvar("varName", "varValue") 707 | 708 | # * Get user variable and print it 709 | # data = keyauthapp.getvar("varName") 710 | # print(data) 711 | 712 | # * Get normal variable and print it 713 | # data = keyauthapp.var("varName") 714 | # print(data) 715 | 716 | # * Log message to the server and then to your webhook what is set on app settings 717 | # keyauthapp.log("Message") 718 | 719 | # * Get if the user pc have been blacklisted 720 | # print(f"Blacklisted? : {keyauthapp.checkblacklist()}") 721 | 722 | # * See if the current session is validated 723 | # print(f"Session Validated?: {keyauthapp.check()}") 724 | 725 | 726 | # * example to send normal request with no POST data 727 | # data = keyauthapp.webhook("WebhookID", "?type=resetuser&user=username") 728 | 729 | # * example to send form data 730 | # data = keyauthapp.webhook("WebhookID", "", "type=init&name=test&ownerid=j9Gj0FTemM", "application/x-www-form-urlencoded") 731 | 732 | # * example to send JSON 733 | # data = keyauthapp.webhook("WebhookID", "", "{\"content\": \"webhook message here\",\"embeds\": null}", "application/json") 734 | 735 | # * Get chat messages 736 | # messages = keyauthapp.chatGet("CHANNEL") 737 | 738 | # Messages = "" 739 | # for i in range(len(messages)): 740 | # Messages += datetime.utcfromtimestamp(int(messages[i]["timestamp"])).strftime('%Y-%m-%d %H:%M:%S') + " - " + messages[i]["author"] + ": " + messages[i]["message"] + "\n" 741 | 742 | # print("\n\n" + Messages) 743 | 744 | # * Send chat message 745 | # keyauthapp.chatSend("MESSAGE", "CHANNEL") 746 | 747 | # * Add Application Information to Title 748 | # os.system(f"cls & title KeyAuth Python Example - Total Users: {keyauthapp.app_data.numUsers} - Online Users: {keyauthapp.app_data.onlineUsers} - Total Keys: {keyauthapp.app_data.numKeys}") 749 | 750 | # * Auto-Login Example (THIS IS JUST AN EXAMPLE --> YOU WILL HAVE TO EDIT THE CODE PROBABLY) 751 | # 1. Checking and Reading JSON 752 | 753 | #### Note: Remove the ''' on line 151 and 226 754 | 755 | '''try: 756 | if os.path.isfile('auth.json'): #Checking if the auth file exist 757 | if jsond.load(open("auth.json"))["authusername"] == "": #Checks if the authusername is empty or not 758 | print(""" 759 | 1. Login 760 | 2. Register 761 | """) 762 | ans=input("Select Option: ") #Skipping auto-login bc auth file is empty 763 | if ans=="1": 764 | user = input('Provide username: ') 765 | password = input('Provide password: ') 766 | keyauthapp.login(user,password) 767 | authfile = jsond.load(open("auth.json")) 768 | authfile["authusername"] = user 769 | authfile["authpassword"] = password 770 | jsond.dump(authfile, open('auth.json', 'w'), sort_keys=False, indent=4) 771 | elif ans=="2": 772 | user = input('Provide username: ') 773 | password = input('Provide password: ') 774 | license = input('Provide License: ') 775 | keyauthapp.register(user,password,license) 776 | authfile = jsond.load(open("auth.json")) 777 | authfile["authusername"] = user 778 | authfile["authpassword"] = password 779 | jsond.dump(authfile, open('auth.json', 'w'), sort_keys=False, indent=4) 780 | else: 781 | print("\nNot Valid Option") 782 | os._exit(1) 783 | else: 784 | try: #2. Auto login 785 | with open('auth.json', 'r') as f: 786 | authfile = jsond.load(f) 787 | authuser = authfile.get('authusername') 788 | authpass = authfile.get('authpassword') 789 | keyauthapp.login(authuser,authpass) 790 | except Exception as e: #Error stuff 791 | print(e) 792 | else: #Creating auth file bc its missing 793 | try: 794 | f = open("auth.json", "a") #Writing content 795 | f.write("""{ 796 | "authusername": "", 797 | "authpassword": "" 798 | }""") 799 | f.close() 800 | print (""" 801 | 1. Login 802 | 2. Register 803 | """)#Again skipping auto-login bc the file is empty/missing 804 | ans=input("Select Option: ") 805 | if ans=="1": 806 | user = input('Provide username: ') 807 | password = input('Provide password: ') 808 | keyauthapp.login(user,password) 809 | authfile = jsond.load(open("auth.json")) 810 | authfile["authusername"] = user 811 | authfile["authpassword"] = password 812 | jsond.dump(authfile, open('auth.json', 'w'), sort_keys=False, indent=4) 813 | elif ans=="2": 814 | user = input('Provide username: ') 815 | password = input('Provide password: ') 816 | license = input('Provide License: ') 817 | keyauthapp.register(user,password,license) 818 | authfile = jsond.load(open("auth.json")) 819 | authfile["authusername"] = user 820 | authfile["authpassword"] = password 821 | jsond.dump(authfile, open('auth.json', 'w'), sort_keys=False, indent=4) 822 | else: 823 | print("\nNot Valid Option") 824 | os._exit(1) 825 | except Exception as e: #Error stuff 826 | print(e) 827 | os._exit(1) 828 | except Exception as e: #Error stuff 829 | print(e) 830 | os._exit(1)''' 831 | 832 | # endregion 833 | 834 | 835 | print("\nUser data: ") 836 | print("Username: " + keyauthapp.user_data.username) 837 | print("IP address: " + keyauthapp.user_data.ip) 838 | print("Hardware-Id: " + keyauthapp.user_data.hwid) 839 | # print("Subcription: " + keyauthapp.user_data.subscription) ## Print Subscription "ONE" name 840 | 841 | subs = keyauthapp.user_data.subscriptions # Get all Subscription names, expiry, and timeleft 842 | for i in range(len(subs)): 843 | sub = subs[i]["subscription"] # Subscription from every Sub 844 | expiry = datetime.utcfromtimestamp(int(subs[i]["expiry"])).strftime( 845 | '%Y-%m-%d %H:%M:%S') # Expiry date from every Sub 846 | timeleft = subs[i]["timeleft"] # Timeleft from every Sub 847 | 848 | print(f"[{i + 1} / {len(subs)}] | Subscription: {sub} - Expiry: {expiry} - Timeleft: {timeleft}") 849 | 850 | onlineUsers = keyauthapp.fetchOnline() 851 | OU = "" # KEEP THIS EMPTY FOR NOW, THIS WILL BE USED TO CREATE ONLINE USER STRING. 852 | if onlineUsers is None: 853 | OU = "No online users" 854 | else: 855 | for i in range(len(onlineUsers)): 856 | OU += onlineUsers[i]["credential"] + " " 857 | 858 | print("\n" + OU + "\n") 859 | 860 | print("Created at: " + datetime.utcfromtimestamp(int(keyauthapp.user_data.createdate)).strftime('%Y-%m-%d %H:%M:%S')) 861 | print("Last login at: " + datetime.utcfromtimestamp(int(keyauthapp.user_data.lastlogin)).strftime('%Y-%m-%d %H:%M:%S')) 862 | print("Expires at: " + datetime.utcfromtimestamp(int(keyauthapp.user_data.expires)).strftime('%Y-%m-%d %H:%M:%S')) 863 | print(f"Current Session Validation Status: {keyauthapp.check()}") 864 | print("Exiting in 10 secs....") 865 | sleep(10) 866 | os._exit(1) 867 | -------------------------------------------------------------------------------- /other-examples/method1.py: -------------------------------------------------------------------------------- 1 | import binascii # hex encoding 2 | import hashlib 3 | import json as jsond # json 4 | import os 5 | import platform # check platform 6 | import subprocess # needed for mac device 7 | import sys 8 | import time # sleep before exit 9 | from datetime import datetime 10 | from time import sleep 11 | from uuid import uuid4 # gen random guid 12 | 13 | try: 14 | if os.name == 'nt': 15 | import win32security # get sid (WIN only) 16 | import requests # https requests 17 | from Crypto.Cipher import AES 18 | from Crypto.Hash import SHA256 19 | from Crypto.Util.Padding import pad, unpad 20 | except ModuleNotFoundError: 21 | print("Exception when importing modules") 22 | print("Installing necessary modules....") 23 | if os.path.isfile("requirements.txt"): 24 | os.system("pip install -r requirements.txt") 25 | else: 26 | os.system("pip install pywin32") 27 | os.system("pip install pycryptodome") 28 | os.system("pip install requests") 29 | print("Modules installed!") 30 | time.sleep(1.5) 31 | os._exit(1) 32 | 33 | try: # Connection check 34 | s = requests.Session() # Session 35 | s.get('https://google.com') 36 | except requests.exceptions.RequestException as e: 37 | print(e) 38 | time.sleep(3) 39 | os._exit(1) 40 | 41 | 42 | class api: 43 | 44 | name = ownerid = secret = version = hash_to_check = "" 45 | 46 | def __init__(self, name, ownerid, secret, version, hash_to_check): 47 | self.name = name 48 | 49 | self.ownerid = ownerid 50 | 51 | self.secret = secret 52 | 53 | self.version = version 54 | self.hash_to_check = hash_to_check 55 | self.init() 56 | 57 | sessionid = enckey = "" 58 | initialized = False 59 | 60 | def init(self): 61 | 62 | if self.sessionid != "": 63 | print("You've already initialized!") 64 | time.sleep(2) 65 | os._exit(1) 66 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 67 | 68 | self.enckey = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 69 | 70 | post_data = { 71 | "type": binascii.hexlify(("init").encode()), 72 | "ver": encryption.encrypt(self.version, self.secret, init_iv), 73 | "hash": self.hash_to_check, 74 | "enckey": encryption.encrypt(self.enckey, self.secret, init_iv), 75 | "name": binascii.hexlify(self.name.encode()), 76 | "ownerid": binascii.hexlify(self.ownerid.encode()), 77 | "init_iv": init_iv 78 | } 79 | 80 | response = self.__do_request(post_data) 81 | 82 | if response == "KeyAuth_Invalid": 83 | print("The application doesn't exist") 84 | os._exit(1) 85 | 86 | response = encryption.decrypt(response, self.secret, init_iv) 87 | json = jsond.loads(response) 88 | 89 | if json["message"] == "invalidver": 90 | if json["download"] != "": 91 | print("New Version Available") 92 | download_link = json["download"] 93 | os.system(f"start {download_link}") 94 | os._exit(1) 95 | else: 96 | print("Invalid Version, Contact owner to add download link to latest app version") 97 | os._exit(1) 98 | 99 | if not json["success"]: 100 | print(json["message"]) 101 | os._exit(1) 102 | 103 | self.sessionid = json["sessionid"] 104 | self.initialized = True 105 | self.__load_app_data(json["appinfo"]) 106 | 107 | def register(self, user, password, license, hwid=None): 108 | self.checkinit() 109 | if hwid is None: 110 | hwid = others.get_hwid() 111 | 112 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 113 | 114 | post_data = { 115 | "type": binascii.hexlify(("register").encode()), 116 | "username": encryption.encrypt(user, self.enckey, init_iv), 117 | "pass": encryption.encrypt(password, self.enckey, init_iv), 118 | "key": encryption.encrypt(license, self.enckey, init_iv), 119 | "hwid": encryption.encrypt(hwid, self.enckey, init_iv), 120 | "sessionid": binascii.hexlify(self.sessionid.encode()), 121 | "name": binascii.hexlify(self.name.encode()), 122 | "ownerid": binascii.hexlify(self.ownerid.encode()), 123 | "init_iv": init_iv 124 | } 125 | 126 | response = self.__do_request(post_data) 127 | response = encryption.decrypt(response, self.enckey, init_iv) 128 | json = jsond.loads(response) 129 | 130 | if json["success"]: 131 | print("successfully registered") 132 | self.__load_user_data(json["info"]) 133 | else: 134 | print(json["message"]) 135 | os._exit(1) 136 | 137 | def upgrade(self, user, license): 138 | self.checkinit() 139 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 140 | 141 | post_data = { 142 | "type": binascii.hexlify(("upgrade").encode()), 143 | "username": encryption.encrypt(user, self.enckey, init_iv), 144 | "key": encryption.encrypt(license, self.enckey, init_iv), 145 | "sessionid": binascii.hexlify(self.sessionid.encode()), 146 | "name": binascii.hexlify(self.name.encode()), 147 | "ownerid": binascii.hexlify(self.ownerid.encode()), 148 | "init_iv": init_iv 149 | } 150 | 151 | response = self.__do_request(post_data) 152 | 153 | response = encryption.decrypt(response, self.enckey, init_iv) 154 | 155 | json = jsond.loads(response) 156 | 157 | if json["success"]: 158 | print("successfully upgraded user") 159 | print("please restart program and login") 160 | time.sleep(2) 161 | os._exit(1) 162 | else: 163 | print(json["message"]) 164 | os._exit(1) 165 | 166 | def login(self, user, password, hwid=None): 167 | self.checkinit() 168 | if hwid is None: 169 | hwid = others.get_hwid() 170 | 171 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 172 | 173 | post_data = { 174 | "type": binascii.hexlify(("login").encode()), 175 | "username": encryption.encrypt(user, self.enckey, init_iv), 176 | "pass": encryption.encrypt(password, self.enckey, init_iv), 177 | "hwid": encryption.encrypt(hwid, self.enckey, init_iv), 178 | "sessionid": binascii.hexlify(self.sessionid.encode()), 179 | "name": binascii.hexlify(self.name.encode()), 180 | "ownerid": binascii.hexlify(self.ownerid.encode()), 181 | "init_iv": init_iv 182 | } 183 | 184 | response = self.__do_request(post_data) 185 | 186 | response = encryption.decrypt(response, self.enckey, init_iv) 187 | 188 | json = jsond.loads(response) 189 | 190 | if json["success"]: 191 | self.__load_user_data(json["info"]) 192 | print("successfully logged in") 193 | else: 194 | print(json["message"]) 195 | os._exit(1) 196 | 197 | def license(self, key, hwid=None): 198 | self.checkinit() 199 | if hwid is None: 200 | hwid = others.get_hwid() 201 | 202 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 203 | 204 | post_data = { 205 | "type": binascii.hexlify(("license").encode()), 206 | "key": encryption.encrypt(key, self.enckey, init_iv), 207 | "hwid": encryption.encrypt(hwid, self.enckey, init_iv), 208 | "sessionid": binascii.hexlify(self.sessionid.encode()), 209 | "name": binascii.hexlify(self.name.encode()), 210 | "ownerid": binascii.hexlify(self.ownerid.encode()), 211 | "init_iv": init_iv 212 | } 213 | 214 | response = self.__do_request(post_data) 215 | response = encryption.decrypt(response, self.enckey, init_iv) 216 | 217 | json = jsond.loads(response) 218 | 219 | if json["success"]: 220 | self.__load_user_data(json["info"]) 221 | print("successfully logged into license") 222 | else: 223 | print(json["message"]) 224 | os._exit(1) 225 | 226 | def var(self, name): 227 | self.checkinit() 228 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 229 | 230 | post_data = { 231 | "type": binascii.hexlify(("var").encode()), 232 | "varid": encryption.encrypt(name, self.enckey, init_iv), 233 | "sessionid": binascii.hexlify(self.sessionid.encode()), 234 | "name": binascii.hexlify(self.name.encode()), 235 | "ownerid": binascii.hexlify(self.ownerid.encode()), 236 | "init_iv": init_iv 237 | } 238 | 239 | response = self.__do_request(post_data) 240 | 241 | response = encryption.decrypt(response, self.enckey, init_iv) 242 | 243 | json = jsond.loads(response) 244 | 245 | if json["success"]: 246 | return json["message"] 247 | else: 248 | print(json["message"]) 249 | time.sleep(5) 250 | os._exit(1) 251 | 252 | def getvar(self, var_name): 253 | self.checkinit() 254 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 255 | 256 | post_data = { 257 | "type": binascii.hexlify(("getvar").encode()), 258 | "var": encryption.encrypt(var_name, self.enckey, init_iv), 259 | "sessionid": binascii.hexlify(self.sessionid.encode()), 260 | "name": binascii.hexlify(self.name.encode()), 261 | "ownerid": binascii.hexlify(self.ownerid.encode()), 262 | "init_iv": init_iv 263 | } 264 | response = self.__do_request(post_data) 265 | response = encryption.decrypt(response, self.enckey, init_iv) 266 | json = jsond.loads(response) 267 | 268 | if json["success"]: 269 | return json["response"] 270 | else: 271 | print(json["message"]) 272 | time.sleep(5) 273 | os._exit(1) 274 | 275 | def setvar(self, var_name, var_data): 276 | self.checkinit() 277 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 278 | post_data = { 279 | "type": binascii.hexlify(("setvar").encode()), 280 | "var": encryption.encrypt(var_name, self.enckey, init_iv), 281 | "data": encryption.encrypt(var_data, self.enckey, init_iv), 282 | "sessionid": binascii.hexlify(self.sessionid.encode()), 283 | "name": binascii.hexlify(self.name.encode()), 284 | "ownerid": binascii.hexlify(self.ownerid.encode()), 285 | "init_iv": init_iv 286 | } 287 | response = self.__do_request(post_data) 288 | response = encryption.decrypt(response, self.enckey, init_iv) 289 | json = jsond.loads(response) 290 | 291 | if json["success"]: 292 | return True 293 | else: 294 | print(json["message"]) 295 | time.sleep(5) 296 | os._exit(1) 297 | 298 | def ban(self): 299 | self.checkinit() 300 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 301 | post_data = { 302 | "type": binascii.hexlify(("ban").encode()), 303 | "sessionid": binascii.hexlify(self.sessionid.encode()), 304 | "name": binascii.hexlify(self.name.encode()), 305 | "ownerid": binascii.hexlify(self.ownerid.encode()), 306 | "init_iv": init_iv 307 | } 308 | response = self.__do_request(post_data) 309 | response = encryption.decrypt(response, self.enckey, init_iv) 310 | json = jsond.loads(response) 311 | 312 | if json["success"]: 313 | return True 314 | else: 315 | print(json["message"]) 316 | time.sleep(5) 317 | os._exit(1) 318 | 319 | def file(self, fileid): 320 | self.checkinit() 321 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 322 | 323 | post_data = { 324 | "type": binascii.hexlify(("file").encode()), 325 | "fileid": encryption.encrypt(fileid, self.enckey, init_iv), 326 | "sessionid": binascii.hexlify(self.sessionid.encode()), 327 | "name": binascii.hexlify(self.name.encode()), 328 | "ownerid": binascii.hexlify(self.ownerid.encode()), 329 | "init_iv": init_iv 330 | } 331 | 332 | response = self.__do_request(post_data) 333 | 334 | response = encryption.decrypt(response, self.enckey, init_iv) 335 | 336 | json = jsond.loads(response) 337 | 338 | if not json["success"]: 339 | print(json["message"]) 340 | time.sleep(5) 341 | os._exit(1) 342 | return binascii.unhexlify(json["contents"]) 343 | 344 | def webhook(self, webid, param, body = "", conttype = ""): 345 | self.checkinit() 346 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 347 | 348 | post_data = { 349 | "type": binascii.hexlify(("webhook").encode()), 350 | "webid": encryption.encrypt(webid, self.enckey, init_iv), 351 | "params": encryption.encrypt(param, self.enckey, init_iv), 352 | "body": encryption.encrypt(body, self.enckey, init_iv), 353 | "conttype": encryption.encrypt(conttype, self.enckey, init_iv), 354 | "sessionid": binascii.hexlify(self.sessionid.encode()), 355 | "name": binascii.hexlify(self.name.encode()), 356 | "ownerid": binascii.hexlify(self.ownerid.encode()), 357 | "init_iv": init_iv 358 | } 359 | 360 | response = self.__do_request(post_data) 361 | 362 | response = encryption.decrypt(response, self.enckey, init_iv) 363 | json = jsond.loads(response) 364 | 365 | if json["success"]: 366 | return json["message"] 367 | else: 368 | print(json["message"]) 369 | time.sleep(5) 370 | os._exit(1) 371 | 372 | def check(self): 373 | self.checkinit() 374 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 375 | post_data = { 376 | "type": binascii.hexlify(("check").encode()), 377 | "sessionid": binascii.hexlify(self.sessionid.encode()), 378 | "name": binascii.hexlify(self.name.encode()), 379 | "ownerid": binascii.hexlify(self.ownerid.encode()), 380 | "init_iv": init_iv 381 | } 382 | response = self.__do_request(post_data) 383 | 384 | response = encryption.decrypt(response, self.enckey, init_iv) 385 | json = jsond.loads(response) 386 | if json["success"]: 387 | return True 388 | else: 389 | return False 390 | 391 | def checkblacklist(self): 392 | self.checkinit() 393 | hwid = others.get_hwid() 394 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 395 | post_data = { 396 | "type": binascii.hexlify(("checkblacklist").encode()), 397 | "hwid": encryption.encrypt(hwid, self.enckey, init_iv), 398 | "sessionid": binascii.hexlify(self.sessionid.encode()), 399 | "name": binascii.hexlify(self.name.encode()), 400 | "ownerid": binascii.hexlify(self.ownerid.encode()), 401 | "init_iv": init_iv 402 | } 403 | response = self.__do_request(post_data) 404 | 405 | response = encryption.decrypt(response, self.enckey, init_iv) 406 | json = jsond.loads(response) 407 | if json["success"]: 408 | return True 409 | else: 410 | return False 411 | 412 | def log(self, message): 413 | self.checkinit() 414 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 415 | 416 | post_data = { 417 | "type": binascii.hexlify(("log").encode()), 418 | "pcuser": encryption.encrypt(os.getenv('username'), self.enckey, init_iv), 419 | "message": encryption.encrypt(message, self.enckey, init_iv), 420 | "sessionid": binascii.hexlify(self.sessionid.encode()), 421 | "name": binascii.hexlify(self.name.encode()), 422 | "ownerid": binascii.hexlify(self.ownerid.encode()), 423 | "init_iv": init_iv 424 | } 425 | 426 | self.__do_request(post_data) 427 | 428 | def fetchOnline(self): 429 | self.checkinit() 430 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 431 | 432 | post_data = { 433 | "type": binascii.hexlify(("fetchOnline").encode()), 434 | "sessionid": binascii.hexlify(self.sessionid.encode()), 435 | "name": binascii.hexlify(self.name.encode()), 436 | "ownerid": binascii.hexlify(self.ownerid.encode()), 437 | "init_iv": init_iv 438 | } 439 | 440 | response = self.__do_request(post_data) 441 | response = encryption.decrypt(response, self.enckey, init_iv) 442 | 443 | json = jsond.loads(response) 444 | 445 | if json["success"]: 446 | if len(json["users"]) == 0: 447 | return None # THIS IS ISSUE ON KEYAUTH SERVER SIDE 6.8.2022, so it will return none if it is not an array. 448 | else: 449 | return json["users"] 450 | else: 451 | return None 452 | 453 | def chatGet(self, channel): 454 | self.checkinit() 455 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 456 | 457 | post_data = { 458 | "type": binascii.hexlify(("chatget").encode()), 459 | "channel": encryption.encrypt(channel, self.enckey, init_iv), 460 | "sessionid": binascii.hexlify(self.sessionid.encode()), 461 | "name": binascii.hexlify(self.name.encode()), 462 | "ownerid": binascii.hexlify(self.ownerid.encode()), 463 | "init_iv": init_iv 464 | } 465 | 466 | response = self.__do_request(post_data) 467 | response = encryption.decrypt(response, self.enckey, init_iv) 468 | 469 | json = jsond.loads(response) 470 | 471 | if json["success"]: 472 | return json["messages"] 473 | else: 474 | return None 475 | 476 | def chatSend(self, message, channel): 477 | self.checkinit() 478 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 479 | 480 | post_data = { 481 | "type": binascii.hexlify(("chatsend").encode()), 482 | "message": encryption.encrypt(message, self.enckey, init_iv), 483 | "channel": encryption.encrypt(channel, self.enckey, init_iv), 484 | "sessionid": binascii.hexlify(self.sessionid.encode()), 485 | "name": binascii.hexlify(self.name.encode()), 486 | "ownerid": binascii.hexlify(self.ownerid.encode()), 487 | "init_iv": init_iv 488 | } 489 | 490 | response = self.__do_request(post_data) 491 | response = encryption.decrypt(response, self.enckey, init_iv) 492 | 493 | json = jsond.loads(response) 494 | 495 | if json["success"]: 496 | return True 497 | else: 498 | return False 499 | 500 | def checkinit(self): 501 | if not self.initialized: 502 | print("Initialize first, in order to use the functions") 503 | time.sleep(2) 504 | os._exit(1) 505 | 506 | def __do_request(self, post_data): 507 | try: 508 | rq_out = s.post( 509 | "https://keyauth.win/api/1.0/", data=post_data, timeout=30 510 | ) 511 | return rq_out.text 512 | except requests.exceptions.Timeout: 513 | print("Request timed out") 514 | 515 | class application_data_class: 516 | numUsers = numKeys = app_ver = customer_panel = onlineUsers = "" 517 | # region user_data 518 | 519 | class user_data_class: 520 | username = ip = hwid = expires = createdate = lastlogin = subscription = subscriptions = "" 521 | 522 | user_data = user_data_class() 523 | app_data = application_data_class() 524 | 525 | def __load_app_data(self, data): 526 | self.app_data.numUsers = data["numUsers"] 527 | self.app_data.numKeys = data["numKeys"] 528 | self.app_data.app_ver = data["version"] 529 | self.app_data.customer_panel = data["customerPanelLink"] 530 | self.app_data.onlineUsers = data["numOnlineUsers"] 531 | 532 | def __load_user_data(self, data): 533 | self.user_data.username = data["username"] 534 | self.user_data.ip = data["ip"] 535 | self.user_data.hwid = data["hwid"] 536 | self.user_data.expires = data["subscriptions"][0]["expiry"] 537 | self.user_data.createdate = data["createdate"] 538 | self.user_data.lastlogin = data["lastlogin"] 539 | self.user_data.subscription = data["subscriptions"][0]["subscription"] 540 | self.user_data.subscriptions = data["subscriptions"] 541 | 542 | 543 | class others: 544 | @staticmethod 545 | def get_hwid(): 546 | if platform.system() == "Linux": 547 | with open("/etc/machine-id") as f: 548 | hwid = f.read() 549 | return hwid 550 | elif platform.system() == 'Windows': 551 | winuser = os.getlogin() 552 | sid = win32security.LookupAccountName(None, winuser)[0] 553 | hwid = win32security.ConvertSidToStringSid(sid) 554 | return hwid 555 | elif platform.system() == 'Darwin': 556 | output = subprocess.Popen("ioreg -l | grep IOPlatformSerialNumber", stdout=subprocess.PIPE, shell=True).communicate()[0] 557 | serial = output.decode().split('=', 1)[1].replace(' ', '') 558 | hwid = serial[1:-2] 559 | return hwid 560 | 561 | 562 | 563 | class encryption: 564 | @staticmethod 565 | def encrypt_string(plain_text, key, iv): 566 | plain_text = pad(plain_text, 16) 567 | 568 | aes_instance = AES.new(key, AES.MODE_CBC, iv) 569 | 570 | raw_out = aes_instance.encrypt(plain_text) 571 | 572 | return binascii.hexlify(raw_out) 573 | 574 | @staticmethod 575 | def decrypt_string(cipher_text, key, iv): 576 | cipher_text = binascii.unhexlify(cipher_text) 577 | 578 | aes_instance = AES.new(key, AES.MODE_CBC, iv) 579 | 580 | cipher_text = aes_instance.decrypt(cipher_text) 581 | 582 | return unpad(cipher_text, 16) 583 | 584 | @staticmethod 585 | def encrypt(message, enc_key, iv): 586 | try: 587 | _key = SHA256.new(enc_key.encode()).hexdigest()[:32] 588 | 589 | _iv = SHA256.new(iv.encode()).hexdigest()[:16] 590 | 591 | return encryption.encrypt_string(message.encode(), _key.encode(), _iv.encode()).decode() 592 | except: 593 | print("Invalid Application Information. Long text is secret short text is ownerid. Name is supposed to be app name not username") 594 | os._exit(1) 595 | 596 | @staticmethod 597 | def decrypt(message, enc_key, iv): 598 | try: 599 | _key = SHA256.new(enc_key.encode()).hexdigest()[:32] 600 | 601 | _iv = SHA256.new(iv.encode()).hexdigest()[:16] 602 | 603 | return encryption.decrypt_string(message.encode(), _key.encode(), _iv.encode()).decode() 604 | except: 605 | print("Invalid Application Information. Long text is secret short text is ownerid. Name is supposed to be app name not username") 606 | os._exit(1) 607 | 608 | 609 | # import json as jsond 610 | # ^^ only for auto login/json writing/reading 611 | 612 | # watch setup video if you need help https://www.youtube.com/watch?v=L2eAQOmuUiA 613 | 614 | if sys.version_info.minor < 10: # Python version check (Bypass Patch) 615 | print("[Security] - Python 3.10 or higher is recommended. The bypass will not work on 3.10+") 616 | print("You are using Python {}.{}".format(sys.version_info.major, sys.version_info.minor)) 617 | 618 | if platform.system() == 'Windows': 619 | os.system('cls & title Python Example') # clear console, change title 620 | elif platform.system() == 'Linux': 621 | os.system('clear') # clear console 622 | sys.stdout.write("\x1b]0;Python Example\x07") # change title 623 | elif platform.system() == 'Darwin': 624 | os.system("clear && printf '\e[3J'") # clear console 625 | os.system('''echo - n - e "\033]0;Python Example\007"''') # change title 626 | 627 | print("Initializing") 628 | 629 | 630 | def getchecksum(): 631 | md5_hash = hashlib.md5() 632 | file = open(''.join(sys.argv), "rb") 633 | md5_hash.update(file.read()) 634 | digest = md5_hash.hexdigest() 635 | return digest 636 | 637 | 638 | keyauthapp = api( 639 | name = "", #App name (Manage Applications --> Application name) 640 | ownerid = "", #Owner ID (Account-Settings --> OwnerID) 641 | secret = "", #App secret(Manage Applications --> App credentials code) 642 | version = "1.0", 643 | hash_to_check = getchecksum() 644 | ) 645 | 646 | print(f""" 647 | App data: 648 | Number of users: {keyauthapp.app_data.numUsers} 649 | Number of online users: {keyauthapp.app_data.onlineUsers} 650 | Number of keys: {keyauthapp.app_data.numKeys} 651 | Application Version: {keyauthapp.app_data.app_ver} 652 | Customer panel link: {keyauthapp.app_data.customer_panel} 653 | """) 654 | print(f"Current Session Validation Status: {keyauthapp.check()}") 655 | print(f"Blacklisted? : {keyauthapp.checkblacklist()}") # check if blacklisted, you can edit this and make it exit the program if blacklisted 656 | 657 | 658 | def answer(): 659 | try: 660 | print(""" 661 | 1.Login 662 | 2.Register 663 | 3.Upgrade 664 | 4.License Key Only 665 | """) 666 | ans = input("Select Option: ") 667 | if ans == "1": 668 | user = input('Provide username: ') 669 | password = input('Provide password: ') 670 | keyauthapp.login(user, password) 671 | elif ans == "2": 672 | user = input('Provide username: ') 673 | password = input('Provide password: ') 674 | license = input('Provide License: ') 675 | keyauthapp.register(user, password, license) 676 | elif ans == "3": 677 | user = input('Provide username: ') 678 | license = input('Provide License: ') 679 | keyauthapp.upgrade(user, license) 680 | elif ans == "4": 681 | key = input('Enter your license: ') 682 | keyauthapp.license(key) 683 | else: 684 | print("\nNot Valid Option") 685 | time.sleep(1) 686 | os.system('cls') 687 | answer() 688 | except KeyboardInterrupt: 689 | os._exit(1) 690 | 691 | 692 | answer() 693 | 694 | # region Extra Functions 695 | 696 | # * Download Files form the server to your computer using the download function in the api class 697 | # bytes = keyauthapp.file("FILEID") 698 | # f = open("example.exe", "wb") 699 | # f.write(bytes) 700 | # f.close() 701 | 702 | 703 | # * Set up user variable 704 | # keyauthapp.setvar("varName", "varValue") 705 | 706 | # * Get user variable and print it 707 | # data = keyauthapp.getvar("varName") 708 | # print(data) 709 | 710 | # * Get normal variable and print it 711 | # data = keyauthapp.var("varName") 712 | # print(data) 713 | 714 | # * Log message to the server and then to your webhook what is set on app settings 715 | # keyauthapp.log("Message") 716 | 717 | # * Get if the user pc have been blacklisted 718 | # print(f"Blacklisted? : {keyauthapp.checkblacklist()}") 719 | 720 | # * See if the current session is validated 721 | # print(f"Session Validated?: {keyauthapp.check()}") 722 | 723 | 724 | # * example to send normal request with no POST data 725 | # data = keyauthapp.webhook("WebhookID", "?type=resetuser&user=username") 726 | 727 | # * example to send form data 728 | # data = keyauthapp.webhook("WebhookID", "", "type=init&name=test&ownerid=j9Gj0FTemM", "application/x-www-form-urlencoded") 729 | 730 | # * example to send JSON 731 | # data = keyauthapp.webhook("WebhookID", "", "{\"content\": \"webhook message here\",\"embeds\": null}", "application/json") 732 | 733 | # * Get chat messages 734 | # messages = keyauthapp.chatGet("CHANNEL") 735 | 736 | # Messages = "" 737 | # for i in range(len(messages)): 738 | # Messages += datetime.utcfromtimestamp(int(messages[i]["timestamp"])).strftime('%Y-%m-%d %H:%M:%S') + " - " + messages[i]["author"] + ": " + messages[i]["message"] + "\n" 739 | 740 | # print("\n\n" + Messages) 741 | 742 | # * Send chat message 743 | # keyauthapp.chatSend("MESSAGE", "CHANNEL") 744 | 745 | # * Add Application Information to Title 746 | # os.system(f"cls & title KeyAuth Python Example - Total Users: {keyauthapp.app_data.numUsers} - Online Users: {keyauthapp.app_data.onlineUsers} - Total Keys: {keyauthapp.app_data.numKeys}") 747 | 748 | # * Auto-Login Example (THIS IS JUST AN EXAMPLE --> YOU WILL HAVE TO EDIT THE CODE PROBABLY) 749 | # 1. Checking and Reading JSON 750 | 751 | #### Note: Remove the ''' on line 151 and 226 752 | 753 | '''try: 754 | if os.path.isfile('auth.json'): #Checking if the auth file exist 755 | if jsond.load(open("auth.json"))["authusername"] == "": #Checks if the authusername is empty or not 756 | print(""" 757 | 1. Login 758 | 2. Register 759 | """) 760 | ans=input("Select Option: ") #Skipping auto-login bc auth file is empty 761 | if ans=="1": 762 | user = input('Provide username: ') 763 | password = input('Provide password: ') 764 | keyauthapp.login(user,password) 765 | authfile = jsond.load(open("auth.json")) 766 | authfile["authusername"] = user 767 | authfile["authpassword"] = password 768 | jsond.dump(authfile, open('auth.json', 'w'), sort_keys=False, indent=4) 769 | elif ans=="2": 770 | user = input('Provide username: ') 771 | password = input('Provide password: ') 772 | license = input('Provide License: ') 773 | keyauthapp.register(user,password,license) 774 | authfile = jsond.load(open("auth.json")) 775 | authfile["authusername"] = user 776 | authfile["authpassword"] = password 777 | jsond.dump(authfile, open('auth.json', 'w'), sort_keys=False, indent=4) 778 | else: 779 | print("\nNot Valid Option") 780 | os._exit(1) 781 | else: 782 | try: #2. Auto login 783 | with open('auth.json', 'r') as f: 784 | authfile = jsond.load(f) 785 | authuser = authfile.get('authusername') 786 | authpass = authfile.get('authpassword') 787 | keyauthapp.login(authuser,authpass) 788 | except Exception as e: #Error stuff 789 | print(e) 790 | else: #Creating auth file bc its missing 791 | try: 792 | f = open("auth.json", "a") #Writing content 793 | f.write("""{ 794 | "authusername": "", 795 | "authpassword": "" 796 | }""") 797 | f.close() 798 | print (""" 799 | 1. Login 800 | 2. Register 801 | """)#Again skipping auto-login bc the file is empty/missing 802 | ans=input("Select Option: ") 803 | if ans=="1": 804 | user = input('Provide username: ') 805 | password = input('Provide password: ') 806 | keyauthapp.login(user,password) 807 | authfile = jsond.load(open("auth.json")) 808 | authfile["authusername"] = user 809 | authfile["authpassword"] = password 810 | jsond.dump(authfile, open('auth.json', 'w'), sort_keys=False, indent=4) 811 | elif ans=="2": 812 | user = input('Provide username: ') 813 | password = input('Provide password: ') 814 | license = input('Provide License: ') 815 | keyauthapp.register(user,password,license) 816 | authfile = jsond.load(open("auth.json")) 817 | authfile["authusername"] = user 818 | authfile["authpassword"] = password 819 | jsond.dump(authfile, open('auth.json', 'w'), sort_keys=False, indent=4) 820 | else: 821 | print("\nNot Valid Option") 822 | os._exit(1) 823 | except Exception as e: #Error stuff 824 | print(e) 825 | os._exit(1) 826 | except Exception as e: #Error stuff 827 | print(e) 828 | os._exit(1)''' 829 | 830 | # endregion 831 | 832 | 833 | print("\nUser data: ") 834 | print("Username: " + keyauthapp.user_data.username) 835 | print("IP address: " + keyauthapp.user_data.ip) 836 | print("Hardware-Id: " + keyauthapp.user_data.hwid) 837 | # print("Subcription: " + keyauthapp.user_data.subscription) ## Print Subscription "ONE" name 838 | 839 | subs = keyauthapp.user_data.subscriptions # Get all Subscription names, expiry, and timeleft 840 | for i in range(len(subs)): 841 | sub = subs[i]["subscription"] # Subscription from every Sub 842 | expiry = datetime.utcfromtimestamp(int(subs[i]["expiry"])).strftime( 843 | '%Y-%m-%d %H:%M:%S') # Expiry date from every Sub 844 | timeleft = subs[i]["timeleft"] # Timeleft from every Sub 845 | 846 | print(f"[{i + 1} / {len(subs)}] | Subscription: {sub} - Expiry: {expiry} - Timeleft: {timeleft}") 847 | 848 | onlineUsers = keyauthapp.fetchOnline() 849 | OU = "" # KEEP THIS EMPTY FOR NOW, THIS WILL BE USED TO CREATE ONLINE USER STRING. 850 | if onlineUsers is None: 851 | OU = "No online users" 852 | else: 853 | for i in range(len(onlineUsers)): 854 | OU += onlineUsers[i]["credential"] + " " 855 | 856 | print("\n" + OU + "\n") 857 | 858 | print("Created at: " + datetime.utcfromtimestamp(int(keyauthapp.user_data.createdate)).strftime('%Y-%m-%d %H:%M:%S')) 859 | print("Last login at: " + datetime.utcfromtimestamp(int(keyauthapp.user_data.lastlogin)).strftime('%Y-%m-%d %H:%M:%S')) 860 | print("Expires at: " + datetime.utcfromtimestamp(int(keyauthapp.user_data.expires)).strftime('%Y-%m-%d %H:%M:%S')) 861 | print(f"Current Session Validation Status: {keyauthapp.check()}") 862 | 863 | 864 | # Method 1 865 | # Example 866 | # Put all your code here, remove the example_program function and the "if __name__ == '__main__':" 867 | 868 | def example_program(): 869 | print("\nHello world.") 870 | time.sleep(3) 871 | os._exit(1) 872 | 873 | 874 | if __name__ == '__main__': 875 | example_program() 876 | -------------------------------------------------------------------------------- /other-examples/method2.py: -------------------------------------------------------------------------------- 1 | import binascii # hex encoding 2 | import hashlib 3 | import json as jsond # json 4 | import os 5 | import platform # check platform 6 | import subprocess # needed for mac device 7 | import sys 8 | import time # sleep before exit 9 | from datetime import datetime 10 | from uuid import uuid4 # gen random guid 11 | 12 | 13 | # Method 2 14 | # Example 15 | # Put all your code here, remove the example_program function. This method will only work if you call your functions after login. Line 207 16 | # Create 1 function that will call all the other needed functions. You can also create 1 function and put everything in it. This is all your choice, method 1 would be a better idea. 17 | # This can be exploited with Python code injection, for example injecting a code that will call the function before login. 18 | 19 | 20 | def example_program(): 21 | print("\nHello world.") 22 | time.sleep(3) 23 | os._exit(1) 24 | 25 | 26 | 27 | try: 28 | if os.name == 'nt': 29 | import win32security # get sid (WIN only) 30 | import requests # https requests 31 | from Crypto.Cipher import AES 32 | from Crypto.Hash import SHA256 33 | from Crypto.Util.Padding import pad, unpad 34 | except ModuleNotFoundError: 35 | print("Exception when importing modules") 36 | print("Installing necessary modules....") 37 | if os.path.isfile("requirements.txt"): 38 | os.system("pip install -r requirements.txt") 39 | else: 40 | os.system("pip install pywin32") 41 | os.system("pip install pycryptodome") 42 | os.system("pip install requests") 43 | print("Modules installed!") 44 | time.sleep(1.5) 45 | os._exit(1) 46 | 47 | try: # Connection check 48 | s = requests.Session() # Session 49 | s.get('https://google.com') 50 | except requests.exceptions.RequestException as e: 51 | print(e) 52 | time.sleep(3) 53 | os._exit(1) 54 | 55 | 56 | class api: 57 | 58 | name = ownerid = secret = version = hash_to_check = "" 59 | 60 | def __init__(self, name, ownerid, secret, version, hash_to_check): 61 | self.name = name 62 | 63 | self.ownerid = ownerid 64 | 65 | self.secret = secret 66 | 67 | self.version = version 68 | self.hash_to_check = hash_to_check 69 | self.init() 70 | 71 | sessionid = enckey = "" 72 | initialized = False 73 | 74 | def init(self): 75 | 76 | if self.sessionid != "": 77 | print("You've already initialized!") 78 | time.sleep(2) 79 | os._exit(1) 80 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 81 | 82 | self.enckey = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 83 | 84 | post_data = { 85 | "type": binascii.hexlify(("init").encode()), 86 | "ver": encryption.encrypt(self.version, self.secret, init_iv), 87 | "hash": self.hash_to_check, 88 | "enckey": encryption.encrypt(self.enckey, self.secret, init_iv), 89 | "name": binascii.hexlify(self.name.encode()), 90 | "ownerid": binascii.hexlify(self.ownerid.encode()), 91 | "init_iv": init_iv 92 | } 93 | 94 | response = self.__do_request(post_data) 95 | 96 | if response == "KeyAuth_Invalid": 97 | print("The application doesn't exist") 98 | os._exit(1) 99 | 100 | response = encryption.decrypt(response, self.secret, init_iv) 101 | json = jsond.loads(response) 102 | 103 | if json["message"] == "invalidver": 104 | if json["download"] != "": 105 | print("New Version Available") 106 | download_link = json["download"] 107 | os.system(f"start {download_link}") 108 | os._exit(1) 109 | else: 110 | print("Invalid Version, Contact owner to add download link to latest app version") 111 | os._exit(1) 112 | 113 | if not json["success"]: 114 | print(json["message"]) 115 | os._exit(1) 116 | 117 | self.sessionid = json["sessionid"] 118 | self.initialized = True 119 | self.__load_app_data(json["appinfo"]) 120 | 121 | def register(self, user, password, license, hwid=None): 122 | self.checkinit() 123 | if hwid is None: 124 | hwid = others.get_hwid() 125 | 126 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 127 | 128 | post_data = { 129 | "type": binascii.hexlify(("register").encode()), 130 | "username": encryption.encrypt(user, self.enckey, init_iv), 131 | "pass": encryption.encrypt(password, self.enckey, init_iv), 132 | "key": encryption.encrypt(license, self.enckey, init_iv), 133 | "hwid": encryption.encrypt(hwid, self.enckey, init_iv), 134 | "sessionid": binascii.hexlify(self.sessionid.encode()), 135 | "name": binascii.hexlify(self.name.encode()), 136 | "ownerid": binascii.hexlify(self.ownerid.encode()), 137 | "init_iv": init_iv 138 | } 139 | 140 | response = self.__do_request(post_data) 141 | response = encryption.decrypt(response, self.enckey, init_iv) 142 | json = jsond.loads(response) 143 | 144 | if json["success"]: 145 | print("successfully registered") 146 | self.__load_user_data(json["info"]) 147 | else: 148 | print(json["message"]) 149 | os._exit(1) 150 | 151 | def upgrade(self, user, license): 152 | self.checkinit() 153 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 154 | 155 | post_data = { 156 | "type": binascii.hexlify(("upgrade").encode()), 157 | "username": encryption.encrypt(user, self.enckey, init_iv), 158 | "key": encryption.encrypt(license, self.enckey, init_iv), 159 | "sessionid": binascii.hexlify(self.sessionid.encode()), 160 | "name": binascii.hexlify(self.name.encode()), 161 | "ownerid": binascii.hexlify(self.ownerid.encode()), 162 | "init_iv": init_iv 163 | } 164 | 165 | response = self.__do_request(post_data) 166 | 167 | response = encryption.decrypt(response, self.enckey, init_iv) 168 | 169 | json = jsond.loads(response) 170 | 171 | if json["success"]: 172 | print("successfully upgraded user") 173 | print("please restart program and login") 174 | time.sleep(2) 175 | os._exit(1) 176 | else: 177 | print(json["message"]) 178 | os._exit(1) 179 | 180 | def login(self, user, password, hwid=None): 181 | self.checkinit() 182 | if hwid is None: 183 | hwid = others.get_hwid() 184 | 185 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 186 | 187 | post_data = { 188 | "type": binascii.hexlify(("login").encode()), 189 | "username": encryption.encrypt(user, self.enckey, init_iv), 190 | "pass": encryption.encrypt(password, self.enckey, init_iv), 191 | "hwid": encryption.encrypt(hwid, self.enckey, init_iv), 192 | "sessionid": binascii.hexlify(self.sessionid.encode()), 193 | "name": binascii.hexlify(self.name.encode()), 194 | "ownerid": binascii.hexlify(self.ownerid.encode()), 195 | "init_iv": init_iv 196 | } 197 | 198 | response = self.__do_request(post_data) 199 | 200 | response = encryption.decrypt(response, self.enckey, init_iv) 201 | 202 | json = jsond.loads(response) 203 | 204 | if json["success"]: 205 | self.__load_user_data(json["info"]) 206 | print("successfully logged in") 207 | example_program() 208 | else: 209 | print(json["message"]) 210 | os._exit(1) 211 | 212 | def license(self, key, hwid=None): 213 | self.checkinit() 214 | if hwid is None: 215 | hwid = others.get_hwid() 216 | 217 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 218 | 219 | post_data = { 220 | "type": binascii.hexlify(("license").encode()), 221 | "key": encryption.encrypt(key, self.enckey, init_iv), 222 | "hwid": encryption.encrypt(hwid, self.enckey, init_iv), 223 | "sessionid": binascii.hexlify(self.sessionid.encode()), 224 | "name": binascii.hexlify(self.name.encode()), 225 | "ownerid": binascii.hexlify(self.ownerid.encode()), 226 | "init_iv": init_iv 227 | } 228 | 229 | response = self.__do_request(post_data) 230 | response = encryption.decrypt(response, self.enckey, init_iv) 231 | 232 | json = jsond.loads(response) 233 | 234 | if json["success"]: 235 | self.__load_user_data(json["info"]) 236 | print("successfully logged into license") 237 | else: 238 | print(json["message"]) 239 | os._exit(1) 240 | 241 | def var(self, name): 242 | self.checkinit() 243 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 244 | 245 | post_data = { 246 | "type": binascii.hexlify(("var").encode()), 247 | "varid": encryption.encrypt(name, self.enckey, init_iv), 248 | "sessionid": binascii.hexlify(self.sessionid.encode()), 249 | "name": binascii.hexlify(self.name.encode()), 250 | "ownerid": binascii.hexlify(self.ownerid.encode()), 251 | "init_iv": init_iv 252 | } 253 | 254 | response = self.__do_request(post_data) 255 | 256 | response = encryption.decrypt(response, self.enckey, init_iv) 257 | 258 | json = jsond.loads(response) 259 | 260 | if json["success"]: 261 | return json["message"] 262 | else: 263 | print(json["message"]) 264 | time.sleep(5) 265 | os._exit(1) 266 | 267 | def getvar(self, var_name): 268 | self.checkinit() 269 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 270 | 271 | post_data = { 272 | "type": binascii.hexlify(("getvar").encode()), 273 | "var": encryption.encrypt(var_name, self.enckey, init_iv), 274 | "sessionid": binascii.hexlify(self.sessionid.encode()), 275 | "name": binascii.hexlify(self.name.encode()), 276 | "ownerid": binascii.hexlify(self.ownerid.encode()), 277 | "init_iv": init_iv 278 | } 279 | response = self.__do_request(post_data) 280 | response = encryption.decrypt(response, self.enckey, init_iv) 281 | json = jsond.loads(response) 282 | 283 | if json["success"]: 284 | return json["response"] 285 | else: 286 | print(json["message"]) 287 | time.sleep(5) 288 | os._exit(1) 289 | 290 | def setvar(self, var_name, var_data): 291 | self.checkinit() 292 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 293 | post_data = { 294 | "type": binascii.hexlify(("setvar").encode()), 295 | "var": encryption.encrypt(var_name, self.enckey, init_iv), 296 | "data": encryption.encrypt(var_data, self.enckey, init_iv), 297 | "sessionid": binascii.hexlify(self.sessionid.encode()), 298 | "name": binascii.hexlify(self.name.encode()), 299 | "ownerid": binascii.hexlify(self.ownerid.encode()), 300 | "init_iv": init_iv 301 | } 302 | response = self.__do_request(post_data) 303 | response = encryption.decrypt(response, self.enckey, init_iv) 304 | json = jsond.loads(response) 305 | 306 | if json["success"]: 307 | return True 308 | else: 309 | print(json["message"]) 310 | time.sleep(5) 311 | os._exit(1) 312 | 313 | def ban(self): 314 | self.checkinit() 315 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 316 | post_data = { 317 | "type": binascii.hexlify(("ban").encode()), 318 | "sessionid": binascii.hexlify(self.sessionid.encode()), 319 | "name": binascii.hexlify(self.name.encode()), 320 | "ownerid": binascii.hexlify(self.ownerid.encode()), 321 | "init_iv": init_iv 322 | } 323 | response = self.__do_request(post_data) 324 | response = encryption.decrypt(response, self.enckey, init_iv) 325 | json = jsond.loads(response) 326 | 327 | if json["success"]: 328 | return True 329 | else: 330 | print(json["message"]) 331 | time.sleep(5) 332 | os._exit(1) 333 | 334 | def file(self, fileid): 335 | self.checkinit() 336 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 337 | 338 | post_data = { 339 | "type": binascii.hexlify(("file").encode()), 340 | "fileid": encryption.encrypt(fileid, self.enckey, init_iv), 341 | "sessionid": binascii.hexlify(self.sessionid.encode()), 342 | "name": binascii.hexlify(self.name.encode()), 343 | "ownerid": binascii.hexlify(self.ownerid.encode()), 344 | "init_iv": init_iv 345 | } 346 | 347 | response = self.__do_request(post_data) 348 | 349 | response = encryption.decrypt(response, self.enckey, init_iv) 350 | 351 | json = jsond.loads(response) 352 | 353 | if not json["success"]: 354 | print(json["message"]) 355 | time.sleep(5) 356 | os._exit(1) 357 | return binascii.unhexlify(json["contents"]) 358 | 359 | def webhook(self, webid, param, body = "", conttype = ""): 360 | self.checkinit() 361 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 362 | 363 | post_data = { 364 | "type": binascii.hexlify(("webhook").encode()), 365 | "webid": encryption.encrypt(webid, self.enckey, init_iv), 366 | "params": encryption.encrypt(param, self.enckey, init_iv), 367 | "body": encryption.encrypt(body, self.enckey, init_iv), 368 | "conttype": encryption.encrypt(conttype, self.enckey, init_iv), 369 | "sessionid": binascii.hexlify(self.sessionid.encode()), 370 | "name": binascii.hexlify(self.name.encode()), 371 | "ownerid": binascii.hexlify(self.ownerid.encode()), 372 | "init_iv": init_iv 373 | } 374 | 375 | response = self.__do_request(post_data) 376 | 377 | response = encryption.decrypt(response, self.enckey, init_iv) 378 | json = jsond.loads(response) 379 | 380 | if json["success"]: 381 | return json["message"] 382 | else: 383 | print(json["message"]) 384 | time.sleep(5) 385 | os._exit(1) 386 | 387 | def check(self): 388 | self.checkinit() 389 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 390 | post_data = { 391 | "type": binascii.hexlify(("check").encode()), 392 | "sessionid": binascii.hexlify(self.sessionid.encode()), 393 | "name": binascii.hexlify(self.name.encode()), 394 | "ownerid": binascii.hexlify(self.ownerid.encode()), 395 | "init_iv": init_iv 396 | } 397 | response = self.__do_request(post_data) 398 | 399 | response = encryption.decrypt(response, self.enckey, init_iv) 400 | json = jsond.loads(response) 401 | if json["success"]: 402 | return True 403 | else: 404 | return False 405 | 406 | def checkblacklist(self): 407 | self.checkinit() 408 | hwid = others.get_hwid() 409 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 410 | post_data = { 411 | "type": binascii.hexlify(("checkblacklist").encode()), 412 | "hwid": encryption.encrypt(hwid, self.enckey, init_iv), 413 | "sessionid": binascii.hexlify(self.sessionid.encode()), 414 | "name": binascii.hexlify(self.name.encode()), 415 | "ownerid": binascii.hexlify(self.ownerid.encode()), 416 | "init_iv": init_iv 417 | } 418 | response = self.__do_request(post_data) 419 | 420 | response = encryption.decrypt(response, self.enckey, init_iv) 421 | json = jsond.loads(response) 422 | if json["success"]: 423 | return True 424 | else: 425 | return False 426 | 427 | def log(self, message): 428 | self.checkinit() 429 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 430 | 431 | post_data = { 432 | "type": binascii.hexlify(("log").encode()), 433 | "pcuser": encryption.encrypt(os.getenv('username'), self.enckey, init_iv), 434 | "message": encryption.encrypt(message, self.enckey, init_iv), 435 | "sessionid": binascii.hexlify(self.sessionid.encode()), 436 | "name": binascii.hexlify(self.name.encode()), 437 | "ownerid": binascii.hexlify(self.ownerid.encode()), 438 | "init_iv": init_iv 439 | } 440 | 441 | self.__do_request(post_data) 442 | 443 | def fetchOnline(self): 444 | self.checkinit() 445 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 446 | 447 | post_data = { 448 | "type": binascii.hexlify(("fetchOnline").encode()), 449 | "sessionid": binascii.hexlify(self.sessionid.encode()), 450 | "name": binascii.hexlify(self.name.encode()), 451 | "ownerid": binascii.hexlify(self.ownerid.encode()), 452 | "init_iv": init_iv 453 | } 454 | 455 | response = self.__do_request(post_data) 456 | response = encryption.decrypt(response, self.enckey, init_iv) 457 | 458 | json = jsond.loads(response) 459 | 460 | if json["success"]: 461 | if len(json["users"]) == 0: 462 | return None # THIS IS ISSUE ON KEYAUTH SERVER SIDE 6.8.2022, so it will return none if it is not an array. 463 | else: 464 | return json["users"] 465 | else: 466 | return None 467 | 468 | def chatGet(self, channel): 469 | self.checkinit() 470 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 471 | 472 | post_data = { 473 | "type": binascii.hexlify(("chatget").encode()), 474 | "channel": encryption.encrypt(channel, self.enckey, init_iv), 475 | "sessionid": binascii.hexlify(self.sessionid.encode()), 476 | "name": binascii.hexlify(self.name.encode()), 477 | "ownerid": binascii.hexlify(self.ownerid.encode()), 478 | "init_iv": init_iv 479 | } 480 | 481 | response = self.__do_request(post_data) 482 | response = encryption.decrypt(response, self.enckey, init_iv) 483 | 484 | json = jsond.loads(response) 485 | 486 | if json["success"]: 487 | return json["messages"] 488 | else: 489 | return None 490 | 491 | def chatSend(self, message, channel): 492 | self.checkinit() 493 | init_iv = SHA256.new(str(uuid4())[:8].encode()).hexdigest() 494 | 495 | post_data = { 496 | "type": binascii.hexlify(("chatsend").encode()), 497 | "message": encryption.encrypt(message, self.enckey, init_iv), 498 | "channel": encryption.encrypt(channel, self.enckey, init_iv), 499 | "sessionid": binascii.hexlify(self.sessionid.encode()), 500 | "name": binascii.hexlify(self.name.encode()), 501 | "ownerid": binascii.hexlify(self.ownerid.encode()), 502 | "init_iv": init_iv 503 | } 504 | 505 | response = self.__do_request(post_data) 506 | response = encryption.decrypt(response, self.enckey, init_iv) 507 | 508 | json = jsond.loads(response) 509 | 510 | if json["success"]: 511 | return True 512 | else: 513 | return False 514 | 515 | def checkinit(self): 516 | if not self.initialized: 517 | print("Initialize first, in order to use the functions") 518 | time.sleep(2) 519 | os._exit(1) 520 | 521 | def __do_request(self, post_data): 522 | try: 523 | rq_out = s.post( 524 | "https://keyauth.win/api/1.0/", data=post_data, timeout=30 525 | ) 526 | return rq_out.text 527 | except requests.exceptions.Timeout: 528 | print("Request timed out") 529 | 530 | class application_data_class: 531 | numUsers = numKeys = app_ver = customer_panel = onlineUsers = "" 532 | # region user_data 533 | 534 | class user_data_class: 535 | username = ip = hwid = expires = createdate = lastlogin = subscription = subscriptions = "" 536 | 537 | user_data = user_data_class() 538 | app_data = application_data_class() 539 | 540 | def __load_app_data(self, data): 541 | self.app_data.numUsers = data["numUsers"] 542 | self.app_data.numKeys = data["numKeys"] 543 | self.app_data.app_ver = data["version"] 544 | self.app_data.customer_panel = data["customerPanelLink"] 545 | self.app_data.onlineUsers = data["numOnlineUsers"] 546 | 547 | def __load_user_data(self, data): 548 | self.user_data.username = data["username"] 549 | self.user_data.ip = data["ip"] 550 | self.user_data.hwid = data["hwid"] 551 | self.user_data.expires = data["subscriptions"][0]["expiry"] 552 | self.user_data.createdate = data["createdate"] 553 | self.user_data.lastlogin = data["lastlogin"] 554 | self.user_data.subscription = data["subscriptions"][0]["subscription"] 555 | self.user_data.subscriptions = data["subscriptions"] 556 | 557 | 558 | class others: 559 | @staticmethod 560 | def get_hwid(): 561 | if platform.system() == "Linux": 562 | with open("/etc/machine-id") as f: 563 | hwid = f.read() 564 | return hwid 565 | elif platform.system() == 'Windows': 566 | winuser = os.getlogin() 567 | sid = win32security.LookupAccountName(None, winuser)[0] 568 | hwid = win32security.ConvertSidToStringSid(sid) 569 | return hwid 570 | elif platform.system() == 'Darwin': 571 | output = subprocess.Popen("ioreg -l | grep IOPlatformSerialNumber", stdout=subprocess.PIPE, shell=True).communicate()[0] 572 | serial = output.decode().split('=', 1)[1].replace(' ', '') 573 | hwid = serial[1:-2] 574 | return hwid 575 | 576 | 577 | 578 | class encryption: 579 | @staticmethod 580 | def encrypt_string(plain_text, key, iv): 581 | plain_text = pad(plain_text, 16) 582 | 583 | aes_instance = AES.new(key, AES.MODE_CBC, iv) 584 | 585 | raw_out = aes_instance.encrypt(plain_text) 586 | 587 | return binascii.hexlify(raw_out) 588 | 589 | @staticmethod 590 | def decrypt_string(cipher_text, key, iv): 591 | cipher_text = binascii.unhexlify(cipher_text) 592 | 593 | aes_instance = AES.new(key, AES.MODE_CBC, iv) 594 | 595 | cipher_text = aes_instance.decrypt(cipher_text) 596 | 597 | return unpad(cipher_text, 16) 598 | 599 | @staticmethod 600 | def encrypt(message, enc_key, iv): 601 | try: 602 | _key = SHA256.new(enc_key.encode()).hexdigest()[:32] 603 | 604 | _iv = SHA256.new(iv.encode()).hexdigest()[:16] 605 | 606 | return encryption.encrypt_string(message.encode(), _key.encode(), _iv.encode()).decode() 607 | except: 608 | print("Invalid Application Information. Long text is secret short text is ownerid. Name is supposed to be app name not username") 609 | os._exit(1) 610 | 611 | @staticmethod 612 | def decrypt(message, enc_key, iv): 613 | try: 614 | _key = SHA256.new(enc_key.encode()).hexdigest()[:32] 615 | 616 | _iv = SHA256.new(iv.encode()).hexdigest()[:16] 617 | 618 | return encryption.decrypt_string(message.encode(), _key.encode(), _iv.encode()).decode() 619 | except: 620 | print("Invalid Application Information. Long text is secret short text is ownerid. Name is supposed to be app name not username") 621 | os._exit(1) 622 | 623 | 624 | # import json as jsond 625 | # ^^ only for auto login/json writing/reading 626 | 627 | # watch setup video if you need help https://www.youtube.com/watch?v=L2eAQOmuUiA 628 | 629 | if sys.version_info.minor < 10: # Python version check (Bypass Patch) 630 | print("[Security] - Python 3.10 or higher is recommended. The bypass will not work on 3.10+") 631 | print("You are using Python {}.{}".format(sys.version_info.major, sys.version_info.minor)) 632 | 633 | if platform.system() == 'Windows': 634 | os.system('cls & title Python Example') # clear console, change title 635 | elif platform.system() == 'Linux': 636 | os.system('clear') # clear console 637 | sys.stdout.write("\x1b]0;Python Example\x07") # change title 638 | elif platform.system() == 'Darwin': 639 | os.system("clear && printf '\e[3J'") # clear console 640 | os.system('''echo - n - e "\033]0;Python Example\007"''') # change title 641 | 642 | print("Initializing") 643 | 644 | 645 | def getchecksum(): 646 | md5_hash = hashlib.md5() 647 | file = open(''.join(sys.argv), "rb") 648 | md5_hash.update(file.read()) 649 | digest = md5_hash.hexdigest() 650 | return digest 651 | 652 | 653 | keyauthapp = api( 654 | name = "", #App name (Manage Applications --> Application name) 655 | ownerid = "", #Owner ID (Account-Settings --> OwnerID) 656 | secret = "", #App secret(Manage Applications --> App credentials code) 657 | version = "1.0", 658 | hash_to_check = getchecksum() 659 | ) 660 | 661 | print(f""" 662 | App data: 663 | Number of users: {keyauthapp.app_data.numUsers} 664 | Number of online users: {keyauthapp.app_data.onlineUsers} 665 | Number of keys: {keyauthapp.app_data.numKeys} 666 | Application Version: {keyauthapp.app_data.app_ver} 667 | Customer panel link: {keyauthapp.app_data.customer_panel} 668 | """) 669 | print(f"Current Session Validation Status: {keyauthapp.check()}") 670 | print(f"Blacklisted? : {keyauthapp.checkblacklist()}") # check if blacklisted, you can edit this and make it exit the program if blacklisted 671 | 672 | 673 | def answer(): 674 | try: 675 | print(""" 676 | 1.Login 677 | 2.Register 678 | 3.Upgrade 679 | 4.License Key Only 680 | """) 681 | ans = input("Select Option: ") 682 | if ans == "1": 683 | user = input('Provide username: ') 684 | password = input('Provide password: ') 685 | keyauthapp.login(user, password) 686 | elif ans == "2": 687 | user = input('Provide username: ') 688 | password = input('Provide password: ') 689 | license = input('Provide License: ') 690 | keyauthapp.register(user, password, license) 691 | elif ans == "3": 692 | user = input('Provide username: ') 693 | license = input('Provide License: ') 694 | keyauthapp.upgrade(user, license) 695 | elif ans == "4": 696 | key = input('Enter your license: ') 697 | keyauthapp.license(key) 698 | else: 699 | print("\nNot Valid Option") 700 | time.sleep(1) 701 | os.system('cls') 702 | answer() 703 | except KeyboardInterrupt: 704 | os._exit(1) 705 | 706 | 707 | answer() 708 | 709 | # region Extra Functions 710 | 711 | # * Download Files form the server to your computer using the download function in the api class 712 | # bytes = keyauthapp.file("FILEID") 713 | # f = open("example.exe", "wb") 714 | # f.write(bytes) 715 | # f.close() 716 | 717 | 718 | # * Set up user variable 719 | # keyauthapp.setvar("varName", "varValue") 720 | 721 | # * Get user variable and print it 722 | # data = keyauthapp.getvar("varName") 723 | # print(data) 724 | 725 | # * Get normal variable and print it 726 | # data = keyauthapp.var("varName") 727 | # print(data) 728 | 729 | # * Log message to the server and then to your webhook what is set on app settings 730 | # keyauthapp.log("Message") 731 | 732 | # * Get if the user pc have been blacklisted 733 | # print(f"Blacklisted? : {keyauthapp.checkblacklist()}") 734 | 735 | # * See if the current session is validated 736 | # print(f"Session Validated?: {keyauthapp.check()}") 737 | 738 | 739 | # * example to send normal request with no POST data 740 | # data = keyauthapp.webhook("WebhookID", "?type=resetuser&user=username") 741 | 742 | # * example to send form data 743 | # data = keyauthapp.webhook("WebhookID", "", "type=init&name=test&ownerid=j9Gj0FTemM", "application/x-www-form-urlencoded") 744 | 745 | # * example to send JSON 746 | # data = keyauthapp.webhook("WebhookID", "", "{\"content\": \"webhook message here\",\"embeds\": null}", "application/json") 747 | 748 | # * Get chat messages 749 | # messages = keyauthapp.chatGet("CHANNEL") 750 | 751 | # Messages = "" 752 | # for i in range(len(messages)): 753 | # Messages += datetime.utcfromtimestamp(int(messages[i]["timestamp"])).strftime('%Y-%m-%d %H:%M:%S') + " - " + messages[i]["author"] + ": " + messages[i]["message"] + "\n" 754 | 755 | # print("\n\n" + Messages) 756 | 757 | # * Send chat message 758 | # keyauthapp.chatSend("MESSAGE", "CHANNEL") 759 | 760 | # * Add Application Information to Title 761 | # os.system(f"cls & title KeyAuth Python Example - Total Users: {keyauthapp.app_data.numUsers} - Online Users: {keyauthapp.app_data.onlineUsers} - Total Keys: {keyauthapp.app_data.numKeys}") 762 | 763 | # * Auto-Login Example (THIS IS JUST AN EXAMPLE --> YOU WILL HAVE TO EDIT THE CODE PROBABLY) 764 | # 1. Checking and Reading JSON 765 | 766 | #### Note: Remove the ''' on line 151 and 226 767 | 768 | '''try: 769 | if os.path.isfile('auth.json'): #Checking if the auth file exist 770 | if jsond.load(open("auth.json"))["authusername"] == "": #Checks if the authusername is empty or not 771 | print(""" 772 | 1. Login 773 | 2. Register 774 | """) 775 | ans=input("Select Option: ") #Skipping auto-login bc auth file is empty 776 | if ans=="1": 777 | user = input('Provide username: ') 778 | password = input('Provide password: ') 779 | keyauthapp.login(user,password) 780 | authfile = jsond.load(open("auth.json")) 781 | authfile["authusername"] = user 782 | authfile["authpassword"] = password 783 | jsond.dump(authfile, open('auth.json', 'w'), sort_keys=False, indent=4) 784 | elif ans=="2": 785 | user = input('Provide username: ') 786 | password = input('Provide password: ') 787 | license = input('Provide License: ') 788 | keyauthapp.register(user,password,license) 789 | authfile = jsond.load(open("auth.json")) 790 | authfile["authusername"] = user 791 | authfile["authpassword"] = password 792 | jsond.dump(authfile, open('auth.json', 'w'), sort_keys=False, indent=4) 793 | else: 794 | print("\nNot Valid Option") 795 | os._exit(1) 796 | else: 797 | try: #2. Auto login 798 | with open('auth.json', 'r') as f: 799 | authfile = jsond.load(f) 800 | authuser = authfile.get('authusername') 801 | authpass = authfile.get('authpassword') 802 | keyauthapp.login(authuser,authpass) 803 | except Exception as e: #Error stuff 804 | print(e) 805 | else: #Creating auth file bc its missing 806 | try: 807 | f = open("auth.json", "a") #Writing content 808 | f.write("""{ 809 | "authusername": "", 810 | "authpassword": "" 811 | }""") 812 | f.close() 813 | print (""" 814 | 1. Login 815 | 2. Register 816 | """)#Again skipping auto-login bc the file is empty/missing 817 | ans=input("Select Option: ") 818 | if ans=="1": 819 | user = input('Provide username: ') 820 | password = input('Provide password: ') 821 | keyauthapp.login(user,password) 822 | authfile = jsond.load(open("auth.json")) 823 | authfile["authusername"] = user 824 | authfile["authpassword"] = password 825 | jsond.dump(authfile, open('auth.json', 'w'), sort_keys=False, indent=4) 826 | elif ans=="2": 827 | user = input('Provide username: ') 828 | password = input('Provide password: ') 829 | license = input('Provide License: ') 830 | keyauthapp.register(user,password,license) 831 | authfile = jsond.load(open("auth.json")) 832 | authfile["authusername"] = user 833 | authfile["authpassword"] = password 834 | jsond.dump(authfile, open('auth.json', 'w'), sort_keys=False, indent=4) 835 | else: 836 | print("\nNot Valid Option") 837 | os._exit(1) 838 | except Exception as e: #Error stuff 839 | print(e) 840 | os._exit(1) 841 | except Exception as e: #Error stuff 842 | print(e) 843 | os._exit(1)''' 844 | 845 | # endregion 846 | 847 | 848 | print("\nUser data: ") 849 | print("Username: " + keyauthapp.user_data.username) 850 | print("IP address: " + keyauthapp.user_data.ip) 851 | print("Hardware-Id: " + keyauthapp.user_data.hwid) 852 | # print("Subcription: " + keyauthapp.user_data.subscription) ## Print Subscription "ONE" name 853 | 854 | subs = keyauthapp.user_data.subscriptions # Get all Subscription names, expiry, and timeleft 855 | for i in range(len(subs)): 856 | sub = subs[i]["subscription"] # Subscription from every Sub 857 | expiry = datetime.utcfromtimestamp(int(subs[i]["expiry"])).strftime( 858 | '%Y-%m-%d %H:%M:%S') # Expiry date from every Sub 859 | timeleft = subs[i]["timeleft"] # Timeleft from every Sub 860 | 861 | print(f"[{i + 1} / {len(subs)}] | Subscription: {sub} - Expiry: {expiry} - Timeleft: {timeleft}") 862 | 863 | onlineUsers = keyauthapp.fetchOnline() 864 | OU = "" # KEEP THIS EMPTY FOR NOW, THIS WILL BE USED TO CREATE ONLINE USER STRING. 865 | if onlineUsers is None: 866 | OU = "No online users" 867 | else: 868 | for i in range(len(onlineUsers)): 869 | OU += onlineUsers[i]["credential"] + " " 870 | 871 | print("\n" + OU + "\n") 872 | 873 | print("Created at: " + datetime.utcfromtimestamp(int(keyauthapp.user_data.createdate)).strftime('%Y-%m-%d %H:%M:%S')) 874 | print("Last login at: " + datetime.utcfromtimestamp(int(keyauthapp.user_data.lastlogin)).strftime('%Y-%m-%d %H:%M:%S')) 875 | print("Expires at: " + datetime.utcfromtimestamp(int(keyauthapp.user_data.expires)).strftime('%Y-%m-%d %H:%M:%S')) 876 | print(f"Current Session Validation Status: {keyauthapp.check()}") 877 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | pywin32 3 | discord-interactions 4 | qrcode 5 | pillow 6 | --------------------------------------------------------------------------------