mirror of
https://github.com/Sneed-Group/pypush-plus-plus
synced 2024-12-24 03:42:43 -06:00
108 lines
No EOL
4.4 KiB
Python
108 lines
No EOL
4.4 KiB
Python
from cryptography.hazmat.primitives.asymmetric import ec
|
|
from cryptography.hazmat.primitives.asymmetric import rsa
|
|
from cryptography.hazmat.primitives import serialization
|
|
|
|
from base64 import b64decode, b64encode
|
|
|
|
from io import BytesIO
|
|
|
|
def generate_keys() -> tuple[str, str, 'IdentityKeys']:
|
|
"""
|
|
ECDSA key, RSA key, IdentityKeys
|
|
"""
|
|
ecdsa_key = ec.generate_private_key(ec.SECP256R1())
|
|
rsa_key = rsa.generate_private_key(65537, 1280)
|
|
|
|
# Serialize the keys into PEM
|
|
ecdsa_key_p = ecdsa_key.private_bytes(
|
|
encoding=serialization.Encoding.PEM,
|
|
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
|
encryption_algorithm=serialization.NoEncryption(),
|
|
).decode("utf-8").strip()
|
|
rsa_key_p = rsa_key.private_bytes(
|
|
encoding=serialization.Encoding.PEM,
|
|
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
|
encryption_algorithm=serialization.NoEncryption(),
|
|
).decode("utf-8").strip()
|
|
return ecdsa_key_p, rsa_key_p, IdentityKeys(ecdsa_key.public_key(), rsa_key.public_key())
|
|
|
|
def load_keys(ecdsa_key_p: str, rsa_key_p: str) -> 'IdentityKeys':
|
|
ecdsa_key = serialization.load_pem_private_key(ecdsa_key_p.encode(), password=None)
|
|
rsa_key = serialization.load_pem_private_key(rsa_key_p.encode(), password=None)
|
|
return IdentityKeys(ecdsa_key.public_key(), rsa_key.public_key())
|
|
|
|
class IdentityKeys():
|
|
def __init__(self, ecdsa_key: ec.EllipticCurvePublicKey, rsa_key: rsa.RSAPublicKey):
|
|
self.ecdsa_key = ecdsa_key
|
|
self.rsa_key = rsa_key
|
|
|
|
def decode(input: bytes) -> 'IdentityKeys':
|
|
input = BytesIO(input)
|
|
|
|
assert input.read(5) == b'\x30\x81\xF6\x81\x43' # DER header
|
|
raw_ecdsa = input.read(67)
|
|
assert input.read(3) == b'\x82\x81\xAE' # DER header
|
|
raw_rsa = input.read(174)
|
|
|
|
# Parse the RSA key
|
|
raw_rsa = BytesIO(raw_rsa)
|
|
assert raw_rsa.read(2) == b'\x00\xAC' # Not sure what this is
|
|
assert raw_rsa.read(3) == b'\x30\x81\xA9' # Inner DER header
|
|
assert raw_rsa.read(3) == b'\x02\x81\xA1'
|
|
rsa_modulus = raw_rsa.read(161)
|
|
rsa_modulus = int.from_bytes(rsa_modulus, "big")
|
|
assert raw_rsa.read(5) == b'\x02\x03\x01\x00\x01' # Exponent, should always be 65537
|
|
|
|
# Parse the EC key
|
|
assert raw_ecdsa[:3] == b'\x00\x41\x04'
|
|
raw_ecdsa = raw_ecdsa[3:]
|
|
ec_x = int.from_bytes(raw_ecdsa[:32], "big")
|
|
ec_y = int.from_bytes(raw_ecdsa[32:], "big")
|
|
|
|
ec_key = ec.EllipticCurvePublicNumbers(ec_x, ec_y, ec.SECP256R1())
|
|
ec_key = ec_key.public_key()
|
|
|
|
rsa_key = rsa.RSAPublicNumbers(e=65537, n=rsa_modulus)
|
|
rsa_key = rsa_key.public_key()
|
|
|
|
return IdentityKeys(ec_key, rsa_key)
|
|
|
|
def encode(self) -> bytes:
|
|
output = BytesIO()
|
|
|
|
raw_rsa = BytesIO()
|
|
raw_rsa.write(b'\x00\xAC')
|
|
raw_rsa.write(b'\x30\x81\xA9')
|
|
raw_rsa.write(b'\x02\x81\xA1')
|
|
raw_rsa.write(self.rsa_key.public_numbers().n.to_bytes(161, "big"))
|
|
raw_rsa.write(b'\x02\x03\x01\x00\x01') # Hardcode the exponent
|
|
|
|
output.write(b'\x30\x81\xF6\x81\x43')
|
|
output.write(b'\x00\x41\x04')
|
|
output.write(self.ecdsa_key.public_numbers().x.to_bytes(32, "big"))
|
|
output.write(self.ecdsa_key.public_numbers().y.to_bytes(32, "big"))
|
|
|
|
output.write(b'\x82\x81\xAE')
|
|
output.write(raw_rsa.getvalue())
|
|
|
|
return output.getvalue()
|
|
|
|
if __name__ == "__main__":
|
|
input_key = """MIH2gUMAQQSYmvE+hYOWVGotZUCd
|
|
M6zoW/2clK8RIzUtE6JAmWSCwj7d
|
|
B213vxEBNAPHefEtlxkVKlQH6bsw
|
|
ja5qYyl3Fh28goGuAKwwgakCgaEA
|
|
4lw3MrXOFIWWIi3TTUGksXVCIz92
|
|
R3AG3ghBa1ZBoZ6rIJHeuxhD2vTV
|
|
hicpW7kvZ/+AFgE4vFFef/9TjG6C
|
|
rsBtWUUfPtYHqc7+uaghVW13qfYC
|
|
tdGsW8Apvf6MJqsRmITJjoYZ5kwl
|
|
scp5Xw/1KVQzKMfZrwZeLC/UZ6O1
|
|
41u4Xvm+u40e+Ky/wMCOwLGBG0Ag
|
|
ZBH91Xrq+S8izgSLmQIDAQAB""".replace("\n", "").replace(" ", "").replace("\t", "")
|
|
keys = IdentityKeys.decode(b64decode(input_key))
|
|
print(b64encode(keys.encode()).decode())
|
|
print(len(keys.encode()))
|
|
print(len(b64decode(input_key)))
|
|
print(keys.encode() == b64decode(input_key))
|
|
print(keys.rsa_key.key_size) |