Skip to content

Commit

Permalink
🗓 Jul 27, 2022 8:43:32 PM
Browse files Browse the repository at this point in the history
🔥 rename crypto_extras to crypto
🔥 rename xor_key_from_files to xor_repeating_key
🔥 breaking: moving from a lot of list returns to string returns
🔍 update to/from_hex to handle delimiters
🔍 update to/from_charcode to handle base and join_by
🔍 update to/from_decimal
🧪 tests added/updated
  • Loading branch information
securisec committed Jul 28, 2022
1 parent 0f09430 commit 32c0a8c
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 57 deletions.
24 changes: 8 additions & 16 deletions chepy/extras/crypto_extras.py → chepy/extras/crypto.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import binascii
import json
from typing import Iterator, Dict, List, Union
from binascii import hexlify, unhexlify
Expand Down Expand Up @@ -78,19 +77,14 @@ def xor_bruteforce_multi(
}


def xor_two_files(file1: str, file2: str) -> bytes: # pragma: no cover
# TODO
pass


def xor_key_from_files(
f1_path: str, f2_path: str, min: int = 1, max: int = 257
def xor_repeating_key(
data1: bytes, data2: bytes, min: int = 1, max: int = 257
) -> Union[bytes, None]: # pragma: no cover
"""XOR two files and get the key.
"""Recover repeating key xor keys.
Args:
f1_path (str): File 1 path
f2_path (str): File 2 path
data1 (bytes): File 1 path
data2 (bytes): File 2 path
min (int, optional): Min chars to test. Defaults to 1.
max (int, optional): Max chars to test. Defaults to 257.
Expand All @@ -103,16 +97,14 @@ def find_same(s: bytes):
return None if i == -1 else s[:i]

for i in range(min, max):
with open(f1_path, "rb") as f:
d1 = f.read(i)
d1 = data1[:i]

with open(f2_path, "rb") as f:
d2 = f.read(i)
d2 = data2[:i]

x = bytes(a ^ b for a, b in zip(d1, d2))
o = find_same(x)
if o is not None:
return binascii.hexlify(o)
return o


def xor(data: bytes, key: bytes) -> bytes: # pragma: no cover
Expand Down
2 changes: 1 addition & 1 deletion chepy/extras/crypto_extras.pyi → chepy/extras/crypto.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ from typing import Dict, Iterator, Union
def factordb(n: int) -> dict: ...
def construct_private_key(n: int, e: int, d: int, format: str=..., passphrase: str=...) -> str: ...
def xor_bruteforce_multi(data: str, min: int=..., max: int=..., errors: str=...) -> Iterator[Dict[str, str]]: ...
def xor_key_from_files(f1_path:str, f2_path: str, min: int =..., max: int = ...) -> Union[bytes, None]: ...
def xor_repeating_key(data1:bytes, data2: bytes, min: int =..., max: int = ...) -> Union[bytes, None]: ...
89 changes: 60 additions & 29 deletions chepy/modules/dataformat.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,31 +437,49 @@ def decode_bytes(self, errors: str = "ignore") -> DataFormatT:
return self

@ChepyDecorators.call_stack
def to_hex(self) -> DataFormatT:
def to_hex(self, delimiter: str = "") -> DataFormatT:
"""Converts a string to its hex representation
Args:
delimiter (str, optional): Delimiter. Defaults to None.
Returns:
Chepy: The Chepy object.
Examples:
>>> Chepy("AAA").to_hex().out().decode()
"414141"
"""
self.state = binascii.hexlify(self._convert_to_bytes())
if delimiter == "":
self.state = binascii.hexlify(self._convert_to_bytes())
else:
self.state = binascii.hexlify(self._convert_to_bytes(), sep=delimiter)
return self

@ChepyDecorators.call_stack
def from_hex(self) -> DataFormatT:
def from_hex(self, delimiter: str = None, join_by: str = " ") -> DataFormatT:
"""Convert a non delimited hex string to string
Args:
delimiter (str, optional): Delimiter. Defaults to None.
join_by (str, optional): Join by. Defaults to ' '.
Returns:
Chepy: The Chepy object.
Examples:
>>> Chepy("414141").from_hex().out()
b"AAA"
"""
self.state = binascii.unhexlify(self._convert_to_bytes())
if delimiter is not None:
self.state = join_by.encode().join(
list(
binascii.unhexlify(x)
for x in self._convert_to_str().split(delimiter)
)
)
else:
self.state = binascii.unhexlify(self._convert_to_str())
return self

@ChepyDecorators.call_stack
Expand Down Expand Up @@ -720,77 +738,90 @@ def str_to_dict(self) -> DataFormatT:
return self

@ChepyDecorators.call_stack
def to_charcode(self, escape_char: str = "") -> DataFormatT:
def to_charcode(self, join_by: str = " ", base: int = 16) -> DataFormatT:
"""Convert a string to a list of unicode charcode
Converts text to its unicode character code equivalent.
e.g. Γειά σου becomes 0393 03b5 03b9 03ac 20 03c3 03bf 03c5
Args:
escape_char (str, optional): Charcater to prepend with. Example \\u, u etc.
@ChepyDecorators.call_stack
Defaults to ''
join_by (str, optional): String to join the charcodes by. Defaults to ' '.
base (int, optional): Base to use for the charcodes. Defaults to 16.
Returns:
Chepy: The Chepy object.
Examples:
>>> Chepy("aㅎ").to_charcode().o
["61", "314e"]
>>> Chepy("aㅎ").to_charcode()
"61 314e"
"""
self.state = list(
"{escape}{hex:02x}".format(escape=escape_char, hex=ord(x))
for x in list(self._convert_to_str())
)
hold = []
for c in self._convert_to_str():
hold.append(str(int(hex(ord(c))[2:], base)))
self.state = join_by.join(hold)
return self

@ChepyDecorators.call_stack
def from_charcode(self, prefix: str = "") -> DataFormatT:
def from_charcode(
self, delimiter: str = " ", join_by: str = "", base: int = 16
) -> DataFormatT:
"""Convert array of unicode chars to string
Args:
prefix (str, optional): Any prefix for the charcode. Ex: \\u or u. Defaults to "".
delimiter (str, optional): Delimiter. Defaults to " ".
join_by (str, optional): Join by. Defaults to "".
base (int, optional): Base. Defaults to 16.
Returns:
Chepy: The Chepy object.
Examples:
>>> Chepy(["314e", "61", "20", "41"]).from_charcode().o
["ㅎ", "a", " ", "A"]
>>> Chepy("314e 61 20 41"]).from_charcode().o
"ㅎa A"
"""
out = []
for c in self.state:
c = re.sub(prefix, "", c)
out.append(chr(int(c, 16)))
self.state = out
for c in self._convert_to_str().split(delimiter):
out.append(chr(int(c, base)))
self.state = join_by.join(out)
return self

@ChepyDecorators.call_stack
def to_decimal(self) -> DataFormatT:
def to_decimal(self, join_by: str = " ") -> DataFormatT:
"""Convert charactes to decimal
Args:
join_by (str, optional): Join the decimal values by this. Defaults to ' '.
Returns:
Chepy: The Chepy object.
Examples:
>>> Chepy("aㅎ").to_decimal().o
[97, 12622]
'97 12622'
"""
self.state = list(ord(s) for s in list(self._convert_to_str()))
self.state = join_by.join(
str(x) for x in list(ord(s) for s in list(self._convert_to_str()))
)
return self

@ChepyDecorators.call_stack
def from_decimal(self) -> DataFormatT:
def from_decimal(self, delimiter: str = " ", join_by: str = "") -> DataFormatT:
"""Convert a list of decimal numbers to string
Args:
delimiter (str, optional): Delimiter. Defaults to " ".
join_by (str, optional): Join by. Defaults to "".
Returns:
Chepy: The Chepy object.
Examples:
>>> Chepy([12622]).from_decimal().o
["ㅎ"]
>>> Chepy(12622).from_decimal().o
"ㅎ"
"""
self.state = list(chr(int(s)) for s in self.state)
self.state = join_by.join(
list(chr(int(s)) for s in self._convert_to_str().strip().split(delimiter))
)
return self

@ChepyDecorators.call_stack
Expand Down
10 changes: 5 additions & 5 deletions chepy/modules/dataformat.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ class DataFormat(ChepyCore):
def base64_encode(self: DataFormatT, custom: str=...) -> DataFormatT: ...
def base64_decode(self: DataFormatT, custom: str=..., fix_padding: bool=...) -> DataFormatT: ...
def decode_bytes(self: DataFormatT, errors: str=...) -> DataFormatT: ...
def to_hex(self: DataFormatT) -> DataFormatT: ...
def from_hex(self: DataFormatT) -> DataFormatT: ...
def to_hex(self: DataFormatT, delimiter: str=..., join_by: str=...) -> DataFormatT: ...
def from_hex(self: DataFormatT, delimiter: str=...) -> DataFormatT: ...
def hex_to_int(self: DataFormatT) -> DataFormatT: ...
def hex_to_binary(self: DataFormatT) -> DataFormatT: ...
def hex_to_str(self: DataFormatT, ignore: bool=...) -> DataFormatT: ...
Expand All @@ -49,10 +49,10 @@ class DataFormat(ChepyCore):
def bytearray_to_str(self: DataFormatT, encoding: str=..., errors: str=...) -> DataFormatT: ...
def str_to_list(self: DataFormatT) -> DataFormatT: ...
def str_to_dict(self: DataFormatT) -> DataFormatT: ...
def to_charcode(self: DataFormatT, escape_char: str=...) -> DataFormatT: ...
def from_charcode(self: DataFormatT, prefix: str=...) -> DataFormatT: ...
def to_charcode(self: DataFormatT, join_by: str=..., base: int=...) -> DataFormatT: ...
def from_charcode(self: DataFormatT, delimiter: str=..., join_by: str=..., base: int=...) -> DataFormatT: ...
def to_decimal(self: DataFormatT) -> DataFormatT: ...
def from_decimal(self: DataFormatT) -> DataFormatT: ...
def from_decimal(self: DataFormatT, delimiter: str=..., join_by: str=...) -> DataFormatT: ...
def to_binary(self: DataFormatT) -> DataFormatT: ...
def from_binary(self: DataFormatT) -> DataFormatT: ...
def to_octal(self: DataFormatT) -> DataFormatT: ...
Expand Down
2 changes: 1 addition & 1 deletion tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def test_cli_options():


def test_fire1():
assert fire.Fire(Chepy, command=["A", "-", "to_hex", "o"]) == b"41"
assert fire.Fire(Chepy, command=["A", "-", "to_hex"]).o == b"41"


def test_fire2():
Expand Down
12 changes: 8 additions & 4 deletions tests/test_dataformat.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,14 @@ def test_base58_encode():

def test_to_hex():
assert Chepy("AAA").to_hex().out().decode() == "414141"
assert Chepy("AAA").to_hex(delimiter=" ").out().decode() == "41 41 41"


def test_from_hex():
assert Chepy("414141").from_hex().out().decode() == "AAA"
assert (
Chepy("41;41;41").from_hex(delimiter=";", join_by="%").out().decode() == "A%A%A"
)


def test_hex_to_int():
Expand Down Expand Up @@ -247,19 +251,19 @@ def test_int_to_str():


def test_to_charcode():
assert Chepy("aㅎ").to_charcode().o == ["61", "314e"]
assert Chepy("aㅎ").to_charcode().o == "97 12622"


def test_from_charcode():
assert Chepy(["314e", "61", "20", "41"]).from_charcode().o == ["ㅎ", "a", " ", "A"]
assert Chepy("314e 61 20 41").from_charcode().o == "ㅎa A"


def test_to_decimal():
assert Chepy("aㅎ").to_decimal().o == [97, 12622]
assert Chepy("aㅎ").to_decimal().o == "97 12622"


def test_from_decimal():
assert Chepy([12622]).from_decimal().o == ["ㅎ"]
assert Chepy(12622).from_decimal().o == "ㅎ"


def test_to_binary():
Expand Down
2 changes: 1 addition & 1 deletion tests/test_extras/test_crypto_extras.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from chepy.extras.crypto_extras import one_time_pad_crib
from chepy.extras.crypto import one_time_pad_crib


def test_one_time_pad_crib():
Expand Down

0 comments on commit 32c0a8c

Please sign in to comment.