├── README.md └── xor.py /README.md: -------------------------------------------------------------------------------- 1 | # Xorpy 2 | 3 | Xorpy is handy XOR encryption tool. This tool takes input from a text file or stdin, and will XOR encrypt it using a user defined key. Due to the nature of bit flipping, the same function that encrypts will also decrypt, assuming you provide the correct key. Use this as a standalone app, or copy/paste it into your own project. It's simple, but works well enough. 4 | 5 | ``` 6 | usage: Xorpy v1.2 [-h] (-k KEY | --bk BK) [-o OUTPUT] [input_file] 7 | 8 | Stupid simple XOR encryption/decryption utility. 9 | 10 | positional arguments: 11 | input_file Input file to read from. If not specified, reads from stdin. 12 | 13 | options: 14 | -h, --help show this help message and exit 15 | -k KEY, --key KEY Clear-text key string. 16 | --bk BK Base64-encoded binary key string. 17 | -o OUTPUT, --output OUTPUT 18 | Output file path for the raw XORd data. If not provided, output will be base64-encoded and printed to stdout. 19 | 20 | Duct taped together by Shawn Evans - sevans@nopsec.com 21 | 22 | ``` 23 | -------------------------------------------------------------------------------- /xor.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import argparse 3 | import base64 4 | import sys 5 | 6 | def xorcrypt(data, key): 7 | """ 8 | Performs XOR encryption/decryption on byte data. 9 | """ 10 | return bytes(a ^ b for a, b in zip(data, key * (len(data) // len(key)) + key[:len(data) % len(key)])) 11 | 12 | def main(): 13 | """ 14 | Main function to parse arguments and run the XOR cipher. 15 | """ 16 | parser = argparse.ArgumentParser( 17 | prog='Xorpy v1.2', 18 | description='Stupid simple XOR encryption/decryption utility.', 19 | formatter_class=argparse.RawTextHelpFormatter, 20 | epilog='Duct taped together by Shawn Evans - sevans@nopsec.com' 21 | ) 22 | 23 | # Mutually exclusive group for key input 24 | key_group = parser.add_mutually_exclusive_group(required=True) 25 | key_group.add_argument( 26 | '-k', '--key', 27 | help='Clear-text key string.' 28 | ) 29 | key_group.add_argument( 30 | '--bk', 31 | help='Base64-encoded binary key string.' 32 | ) 33 | 34 | # Optional arguments 35 | parser.add_argument( 36 | '-o', '--output', 37 | help='Output file path for the raw XORd data. If not provided, output will be base64-encoded and printed to stdout.' 38 | ) 39 | 40 | parser.add_argument( 41 | 'input_file', 42 | nargs='?', 43 | type=argparse.FileType('rb'), 44 | default=sys.stdin.buffer, 45 | help='Input file to read from. If not specified, reads from stdin.' 46 | ) 47 | 48 | args = parser.parse_args() 49 | 50 | # Read input data 51 | input_data = args.input_file.read() 52 | 53 | # Determine the key 54 | if args.key: 55 | key_data = args.key.encode('utf-8') 56 | else: # args.bk 57 | try: 58 | key_data = base64.b64decode(args.bk) 59 | except base64.binascii.Error: 60 | print("Error: The base64 key is not valid.", file=sys.stderr) 61 | sys.exit(1) 62 | 63 | # Perform the XOR operation 64 | result = xorcrypt(input_data, key_data) 65 | 66 | # Handle output 67 | if args.output: 68 | try: 69 | with open(args.output, 'wb') as f: 70 | f.write(result) 71 | print(f"XOR result written to '{args.output}'") 72 | except IOError as e: 73 | print(f"Error writing to file: {e}", file=sys.stderr) 74 | sys.exit(1) 75 | else: 76 | # Base64 encode the result for printing to stdout 77 | encoded_result = base64.b64encode(result).decode('utf-8') 78 | print(encoded_result) 79 | 80 | if __name__ == "__main__": 81 | main() 82 | --------------------------------------------------------------------------------