Il ne manque plus que à envoyer des messages
This commit is contained in:
parent
3f1940df00
commit
93aace85cb
30
RFC8497.md
30
RFC8497.md
@ -141,7 +141,7 @@ Communication entre un client et un noeud
|
||||
###### En-tête ######
|
||||
|
||||
EICP2P2 V1
|
||||
type: register
|
||||
type: register_client
|
||||
|
||||
###### Contenu ######
|
||||
|
||||
@ -160,11 +160,11 @@ Cette requête est envoyée par un client pour s'enregistrer sur le réseau. Le
|
||||
|
||||
###### Contenu ######
|
||||
|
||||
id_noeud::id_client
|
||||
id_noeud{%=&%&=%}id_client
|
||||
|
||||
###### Utilisation ######
|
||||
|
||||
Réponse à un `register`. Le noeud communique au client son id et l'id du noeud auquel il est connecté.
|
||||
Réponse à un `register_client`. Le noeud communique au client son id et l'id du noeud auquel il est connecté.
|
||||
|
||||
### Send ###
|
||||
|
||||
@ -191,7 +191,7 @@ Cette requête est envoyé par un client enregistré à un noeud pour envoyer un
|
||||
|
||||
###### Contenu ######
|
||||
|
||||
Rien
|
||||
Rien/Erreur client incunnu
|
||||
|
||||
###### Utilisation ######
|
||||
|
||||
@ -217,6 +217,28 @@ Cette requête est envoyée par le destinataire d'une requête `send` après avo
|
||||
|
||||
Envoyé par le client pour se déconnecter du réseau. Ne demande aucune réponse de la part du noeud.
|
||||
|
||||
### Get users ###
|
||||
|
||||
###### En-tête ######
|
||||
|
||||
EICP2P2 V1
|
||||
type: getUsers
|
||||
|
||||
###### Contenu ######
|
||||
|
||||
Rien
|
||||
|
||||
### Get User ACK ###
|
||||
|
||||
###### En-tête ######
|
||||
|
||||
EICP2P2 V1
|
||||
type: getUsersACK
|
||||
|
||||
###### Contenu ######
|
||||
|
||||
Listedesutilisateurs
|
||||
|
||||
### Ping ###
|
||||
|
||||
###### En-tête ######
|
||||
|
136
client/main.py
136
client/main.py
@ -18,10 +18,41 @@ try:
|
||||
except ModuleNotFoundError: # Pycryptodomex
|
||||
from Cryptodome.PublicKey import RSA as RSA
|
||||
from Cryptodome.Cipher import PKCS1_OAEP as PKCS1_OAEP
|
||||
from Cryptodome.Cipher import AES as AES
|
||||
|
||||
pycryptodome = True
|
||||
|
||||
|
||||
class RsaGenThread(threading.Thread):
|
||||
|
||||
def __init__(self, client_, difficulty=2):
|
||||
threading.Thread.__init__(self)
|
||||
self.client = client_
|
||||
self.difficulty = difficulty
|
||||
|
||||
def run(self):
|
||||
if os.path.isfile("private.pem"):
|
||||
try:
|
||||
with open("private.pem", "rb") as keyfile:
|
||||
rsa = RSA.importKey(keyfile.read())
|
||||
if not rsa.has_private():
|
||||
warning("Le fichier clef ne contient pas de clef privée")
|
||||
raise ValueError
|
||||
self.client.rsa = rsa
|
||||
except (IndexError, ValueError):
|
||||
warning("Fichier clef corrompu")
|
||||
debug("Suppression du fichier clef corromu")
|
||||
os.remove("private.pem")
|
||||
if not os.path.isfile("private.pem"): # We're not using if/else because we may delete the file in the
|
||||
# previous if statement
|
||||
debug("Génération de la clef RSA pour %s" % self.client.name)
|
||||
self.client.rsa = RSA.generate(BUFFER_SIZE + 256 * self.difficulty)
|
||||
with open("private.pem", "wb") as keyfile:
|
||||
keyfile.write(self.client.rsa.exportKey())
|
||||
with open("public.pem", "wb") as keyfile:
|
||||
keyfile.write(self.client.rsa.publickey().exportKey())
|
||||
|
||||
|
||||
def setup_logging(default_path='log_config.json', default_level=logging.INFO, env_key='LOG_CFG'):
|
||||
"""Setup logging configuration
|
||||
"""
|
||||
@ -58,8 +89,8 @@ NAME = b"client1"
|
||||
VERSION = b"EICP2P2 V1"
|
||||
|
||||
REQUEST_TYPE = [
|
||||
b'ping', b'pingACK', b'updateAsk', b'updateBack', b'transfer', b'register', b'registerACK', b'send', b'sendACK',
|
||||
b'exit', b'RSASend', b'init',
|
||||
b'ping', b'pingACK', b'updateAsk', b'updateBack', b'transfer', b'register_client', b'registerACK', b'send', b'sendACK',
|
||||
b'exit', b'RSASend', b'init', b'getUsers', b'getUsersACK',
|
||||
]
|
||||
|
||||
clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
@ -77,20 +108,38 @@ class MainThread(threading.Thread):
|
||||
self.rsa = None
|
||||
self.aes_key = None
|
||||
self.clientSocket = None
|
||||
self.users = {}
|
||||
|
||||
def run(self):
|
||||
rsa = self.RsaGenThread(self)
|
||||
rsa = RsaGenThread(self)
|
||||
rsa.start()
|
||||
rsa.join()
|
||||
self.clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.clientSocket.connect((HOST, PORT))
|
||||
self.initialisation()
|
||||
self.register()
|
||||
self.get_users()
|
||||
print(self.users)
|
||||
while True:
|
||||
try:
|
||||
type = bytes(input("Type: "), "ascii")
|
||||
contenu = bytes(input("Contenu: "), "ascii")
|
||||
self.send_aes(self.gen_header(type_=type)+contenu)
|
||||
print(self.receive_aes())
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def register(self):
|
||||
self.send_aes(self.gen_header(type_=b"register_client"))
|
||||
self.id_noeud, self.id_client = self.receive_aes()[BUFFER_SIZE:].split(b"{%=&%&=%}")
|
||||
|
||||
def initialisation(self):
|
||||
header = self.gen_header(b"RSASend", from_=b"client")
|
||||
content = self.rsa.publickey().exportKey()
|
||||
self.send(header + content)
|
||||
print("oki1")
|
||||
data = self.receive_rsa()
|
||||
print("oki2")
|
||||
header = self.extract_header(data[:BUFFER_SIZE])
|
||||
if header[b"type"] != b"init":
|
||||
debug("Incorrect request type, end of connection")
|
||||
@ -139,34 +188,60 @@ class MainThread(threading.Thread):
|
||||
header += b"\nfrom: " + from_
|
||||
return header.ljust(BUFFER_SIZE, b';')
|
||||
|
||||
class RsaGenThread(threading.Thread):
|
||||
def get_users(self):
|
||||
self.send_aes(self.gen_header(type_=b'getUsers'))
|
||||
back = self.receive_aes()
|
||||
print(back)
|
||||
header = self.extract_header(back)
|
||||
contenu = back[BUFFER_SIZE:]
|
||||
if header[b"type"] == b"getUsersACK":
|
||||
self.users = [(contenu.split(b"%!!%")[i], i) for i in range(len(contenu.split(b"%!!%")))]
|
||||
|
||||
def __init__(self, client_, difficulty=2):
|
||||
threading.Thread.__init__(self)
|
||||
self.client = client_
|
||||
self.difficulty = difficulty
|
||||
def send_aes(self, to_send, key=None):
|
||||
"""Send message with aes encryption
|
||||
|
||||
def run(self):
|
||||
if os.path.isfile("private.pem"):
|
||||
try:
|
||||
with open("private.pem", "rb") as keyfile:
|
||||
rsa = RSA.importKey(keyfile.read())
|
||||
if not rsa.has_private():
|
||||
warning("Le fichier clef ne contient pas de clef privée")
|
||||
raise ValueError
|
||||
self.client.rsa = rsa
|
||||
except (IndexError, ValueError):
|
||||
warning("Fichier clef corrompu")
|
||||
debug("Suppression du fichier clef corromu")
|
||||
os.remove("private.pem")
|
||||
if not os.path.isfile("private.pem"): # We're not using if/else because we may delete the file in the
|
||||
# previous if statement
|
||||
debug("Génération de la clef RSA pour %s" % self.client.name)
|
||||
self.client.rsa = RSA.generate(BUFFER_SIZE + 256 * self.difficulty)
|
||||
with open("private.pem", "wb") as keyfile:
|
||||
keyfile.write(self.client.rsa.exportKey())
|
||||
with open("public.pem", "wb") as keyfile:
|
||||
keyfile.write(self.client.rsa.publickey().exportKey())
|
||||
:param to_send: Message to send
|
||||
:type to_send: bytes
|
||||
:param key: key to replace self.aes_key
|
||||
:type key: bytes
|
||||
|
||||
:rtype: NoneType
|
||||
:return: Nothing"""
|
||||
debug(b"Send with AES encryption: " + to_send)
|
||||
if key is None:
|
||||
key = self.aes_key
|
||||
if key is None:
|
||||
info("AES key not generated, connection failure.")
|
||||
self.client.send(b"Error")
|
||||
return
|
||||
# Get RSA key
|
||||
aes_object = AES.new(key, AES.MODE_ECB)
|
||||
encrypted = b""
|
||||
for to_send_text in [to_send[i:i + 32] for i in range(0, len(to_send), 32)]:
|
||||
encrypted += aes_object.encrypt(to_send_text.ljust(32, b"\x00"))
|
||||
self.send(encrypted)
|
||||
return None
|
||||
|
||||
def receive_aes(self, key=None):
|
||||
"""Receive message with aes encryption
|
||||
|
||||
:param key: key to replace self.aes_key
|
||||
:type key: bytes
|
||||
"""
|
||||
to_decrypt = self.receive()
|
||||
debug(b"Received in aes "+to_decrypt)
|
||||
if key is None:
|
||||
key = self.aes_key
|
||||
if key is None:
|
||||
info("AES key not generated, connection failure.")
|
||||
self.client.send(b"Error")
|
||||
return
|
||||
aes_object = AES.new(key, AES.MODE_ECB)
|
||||
decrypted = b""
|
||||
for block in [to_decrypt[i:i + 32] for i in range(0, len(to_decrypt), 32)]:
|
||||
print(len(block))
|
||||
decrypted += aes_object.decrypt(block)
|
||||
return decrypted.rstrip(b"\x00")
|
||||
|
||||
################################################ COMMUNICATION WITH RSA ############################################
|
||||
|
||||
@ -180,7 +255,8 @@ class MainThread(threading.Thread):
|
||||
cipher_rsa = PKCS1_OAEP.new(recipient_key)
|
||||
raw = self.receive()
|
||||
content = b""
|
||||
for to_decrypt in [raw[i:i + self.rsa.publickey().size_in_bytes()] for i in range(0, len(raw), self.rsa.publickey().size_in_bytes())]:
|
||||
for to_decrypt in [raw[i:i + self.rsa.publickey().size_in_bytes()] for i in
|
||||
range(0, len(raw), self.rsa.publickey().size_in_bytes())]:
|
||||
content += cipher_rsa.decrypt(to_decrypt)
|
||||
return content
|
||||
|
||||
|
193
server/main.py
193
server/main.py
@ -13,6 +13,7 @@ try:
|
||||
from Crypto.PublicKey import RSA as RSA
|
||||
# noinspection PyUnresolvedReferences
|
||||
from Crypto.Cipher import PKCS1_OAEP as PKCS1_OAEP
|
||||
from Crypto.Cipher import AES as AES
|
||||
# noinspection PyUnresolvedReferences,PyProtectedMember
|
||||
from Crypto.Random._UserFriendlyRNG import get_random_bytes as get_random_bytes
|
||||
|
||||
@ -20,6 +21,7 @@ try:
|
||||
except ModuleNotFoundError: # Pycryptodomex
|
||||
from Cryptodome.PublicKey import RSA as RSA
|
||||
from Cryptodome.Cipher import PKCS1_OAEP as PKCS1_OAEP
|
||||
from Cryptodome.Cipher import AES as AES
|
||||
from Cryptodome.Random import get_random_bytes as get_random_bytes
|
||||
|
||||
pycryptodome = True
|
||||
@ -61,8 +63,8 @@ END_MESSAGE = bytes("fin".ljust(BUFFER_SIZE, ";"), "ascii")
|
||||
VERSION = b"EICP2P2 V1"
|
||||
|
||||
REQUEST_TYPE = [
|
||||
b'ping', b'pingACK', b'updateAsk', b'updateBack', b'transfer', b'register', b'registerACK', b'send', b'sendACK',
|
||||
b'exit', b'RSASend', b'init',
|
||||
b'ping', b'pingACK', b'updateAsk', b'updateBack', b'transfer', b'register_client', b'registerACK', b'send', b'sendACK',
|
||||
b'exit', b'RSASend', b'init', b'getUsers', b'getUsersACK',
|
||||
]
|
||||
|
||||
DONE = 0
|
||||
@ -77,22 +79,99 @@ main_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
main_socket.bind((HOST, PORT))
|
||||
|
||||
|
||||
class ServerThread(threading.Thread):
|
||||
"""Main server thread"""
|
||||
|
||||
#### Threads ####
|
||||
|
||||
class RsaGenThread(threading.Thread):
|
||||
|
||||
def __init__(self, difficulty=2):
|
||||
threading.Thread.__init__(self)
|
||||
self.difficulty = difficulty
|
||||
|
||||
def run(self):
|
||||
rsa = None
|
||||
if os.path.isfile("private.pem"):
|
||||
try:
|
||||
with open("private.pem", "rb") as keyfile:
|
||||
rsa = RSA.importKey(keyfile.read())
|
||||
if not rsa.has_private():
|
||||
warning("Le fichier clef ne contient pas de clef privée")
|
||||
raise ValueError
|
||||
except (IndexError, ValueError):
|
||||
warning("Fichier clef corrompu")
|
||||
debug("Suppression du fichier clef corromu")
|
||||
os.remove("private.pem")
|
||||
if not os.path.isfile("private.pem"): # We're not using if/else because we may delete the file in the
|
||||
# previous if statement
|
||||
rsa = RSA.generate(BUFFER_SIZE + 256 * self.difficulty)
|
||||
with open("private.pem", "wb") as keyfile:
|
||||
keyfile.write(rsa.exportKey())
|
||||
with open("public.pem", "wb") as keyfile:
|
||||
keyfile.write(rsa.publickey().exportKey())
|
||||
return rsa
|
||||
|
||||
|
||||
class ServerThread(threading.Thread):
|
||||
"""Main tread for server"""
|
||||
|
||||
def __init__(self, socket, ip, port):
|
||||
threading.Thread.__init__(self) # initialisation du thread
|
||||
self.socket = socket
|
||||
self.ip = ip
|
||||
self.port = port
|
||||
t = RsaGenThread()
|
||||
self.rsa_key = None
|
||||
if os.path.isfile("private.pem"):
|
||||
try:
|
||||
with open("private.pem", "rb") as keyfile:
|
||||
self.rsa_key = RSA.importKey(keyfile.read())
|
||||
if not self.rsa_key.has_private():
|
||||
warning("Le fichier clef ne contient pas de clef privée")
|
||||
raise ValueError
|
||||
except (IndexError, ValueError):
|
||||
warning("Fichier clef corrompu")
|
||||
debug("Suppression du fichier clef corromu")
|
||||
os.remove("private.pem")
|
||||
if not os.path.isfile("private.pem"): # We're not using if/else because we may delete the file in the
|
||||
# previous if statement
|
||||
debug("Generate new rsa key")
|
||||
self.rsa_key = RSA.generate(BUFFER_SIZE + 256 * self.difficulty)
|
||||
with open("private.pem", "wb") as keyfile:
|
||||
keyfile.write(self.rsa_key.exportKey())
|
||||
with open("public.pem", "wb") as keyfile:
|
||||
keyfile.write(self.rsa_key.publickey().exportKey())
|
||||
debug("RSA key loaded")
|
||||
self.clients = {}
|
||||
self.nodes = {
|
||||
self.rsa_key.publickey().exportKey(): None,
|
||||
}
|
||||
|
||||
def register_client(self, rsa_client, client_thread):
|
||||
self.clients.update({rsa_client: (self.rsa_key, client_thread)})
|
||||
return self.rsa_key.publickey().exportKey(), rsa_client
|
||||
|
||||
def send_to(self, id_dest, to_send):
|
||||
if id_dest not in self.clients.keys():
|
||||
return b"Erreur client inconnu"
|
||||
if self.clients[id_dest][0] is None:
|
||||
return self.clients[id_dest].send_to_me(to_send)
|
||||
else:
|
||||
return self.nodes[self.clients[id_dest]].transfer(id_dest, to_send)
|
||||
|
||||
|
||||
class ClientThread(threading.Thread):
|
||||
"""Main thread, for each client"""
|
||||
|
||||
def __init__(self, clientsocket, ip_client, port):
|
||||
def __init__(self, clientsocket, ip_client, port, server):
|
||||
"""Create ClientThread object
|
||||
|
||||
:param clientsocket: Client's socket
|
||||
:param ip_client: Client's ip address
|
||||
:param port: Client's connection PORT
|
||||
:param server: Server thread
|
||||
:type clientsocket: socket.socket
|
||||
:type ip_client: str
|
||||
:type port: int
|
||||
:type server: ServerThread
|
||||
|
||||
:return: Nothing
|
||||
:rtype: NoneType"""
|
||||
@ -104,8 +183,9 @@ class ClientThread(threading.Thread):
|
||||
self.running = True
|
||||
self.status = None
|
||||
self.rsa_client = None
|
||||
self.aes_key = get_random_bytes(64)
|
||||
self.aes_key = get_random_bytes(32)
|
||||
self.type = T_NONE
|
||||
self.server = server
|
||||
debug("Creation du thread pour %s reussie" % ip_client)
|
||||
|
||||
def initialize(self):
|
||||
@ -181,7 +261,53 @@ class ClientThread(threading.Thread):
|
||||
header += b"\nfrom: " + from_,
|
||||
return header.ljust(BUFFER_SIZE, b';')
|
||||
|
||||
################################################ COMMUNICATION WITH RSA ################################################
|
||||
################################################ COMMUNICATION WITH AES ############################################
|
||||
|
||||
def send_aes(self, to_send, key=None):
|
||||
"""Send message with aes encryption
|
||||
|
||||
:param to_send: Message to send
|
||||
:type to_send: bytes
|
||||
:param key: key to replace self.aes_key
|
||||
:type key: bytes
|
||||
|
||||
:rtype: NoneType
|
||||
:return: Nothing"""
|
||||
debug(b"Send with AES encryption: " + to_send + bytes(str(self.ip), "ascii"))
|
||||
if key is None:
|
||||
key = self.aes_key
|
||||
if key is None:
|
||||
info("AES key not generated, connection failure.")
|
||||
self.client.send(b"Error")
|
||||
return
|
||||
# Get RSA key
|
||||
aes_object = AES.new(key, AES.MODE_ECB)
|
||||
encrypted = b""
|
||||
for to_send_text in [to_send[i:i + 32] for i in range(0, len(to_send), 32)]:
|
||||
encrypted += aes_object.encrypt(to_send_text.ljust(32, b"\x00"))
|
||||
self.send(encrypted)
|
||||
return None
|
||||
|
||||
def receive_aes(self, key=None):
|
||||
"""Receive message with aes encryption
|
||||
|
||||
:param key: key to replace self.aes_key
|
||||
:type key: bytes
|
||||
"""
|
||||
to_decrypt = self.receive()
|
||||
if key is None:
|
||||
key = self.aes_key
|
||||
if key is None:
|
||||
info("AES key not generated, connection failure.")
|
||||
self.client.send(b"Error")
|
||||
return
|
||||
aes_object = AES.new(key, AES.MODE_ECB)
|
||||
decrypted = b""
|
||||
for block in [to_decrypt[i:i + 32] for i in range(0, len(to_decrypt), 32)]:
|
||||
decrypted += aes_object.decrypt(block)
|
||||
return decrypted.rstrip(b"\x00")
|
||||
|
||||
################################################ COMMUNICATION WITH RSA ############################################
|
||||
|
||||
def send_rsa(self, to_send, key=None):
|
||||
"""Send message with rsa encryption
|
||||
@ -210,7 +336,7 @@ class ClientThread(threading.Thread):
|
||||
self.send(encrypted)
|
||||
return None
|
||||
|
||||
############################################ COMMUNICATION WITHOUT CRYPTING ############################################
|
||||
############################################ COMMUNICATION WITHOUT CRYPTING ########################################
|
||||
|
||||
def receive(self):
|
||||
"""Receive message from connection
|
||||
@ -253,6 +379,42 @@ class ClientThread(threading.Thread):
|
||||
self.client.send(END_MESSAGE)
|
||||
return None
|
||||
|
||||
def send_users(self):
|
||||
print(self.server.clients.keys())
|
||||
self.send_aes(self.gen_header(type_=b"getUsersACK")+b"%!!%".join(list(self.server.clients.keys())))
|
||||
|
||||
def register_client(self):
|
||||
"""Register client
|
||||
|
||||
:rtype: NoneType
|
||||
:return: Nothing"""
|
||||
self.server.register_client(self.rsa_client, self)
|
||||
id_noeud, id_client = self.server.rsa_key.publickey().exportKey(), self.rsa_client
|
||||
self.send_aes(self.gen_header(type_=b"registerACK") + id_noeud + b"{%=&%&=%}" + id_client)
|
||||
|
||||
def send_to_me(self, to_send):
|
||||
"""Receive message from other poeple
|
||||
|
||||
:param to_send: Message to send to client
|
||||
:type to_send: bytes
|
||||
|
||||
:rtype: NoneType
|
||||
:return: Nothing"""
|
||||
self.send(self.gen_header(type_=b"send", to_=self.rsa_client) + to_send)
|
||||
return
|
||||
|
||||
def send_to_other(self, id_dest, to_send):
|
||||
"""Send message to other client
|
||||
|
||||
:param id_dest: id of receiver
|
||||
:param to_send: Message to send
|
||||
|
||||
:return: Nothing
|
||||
:rtype: NoneType"""
|
||||
server_response = self.server.send_to(id_dest, to_send)
|
||||
self.send(self.gen_header(type_=b"sendACK"), server_response)
|
||||
return
|
||||
|
||||
def run(self): # main de la connection du client
|
||||
"""Run thread mainloop
|
||||
|
||||
@ -261,14 +423,25 @@ class ClientThread(threading.Thread):
|
||||
info(self.ip + "connected, initialize connection...")
|
||||
self.initialize()
|
||||
info(self.ip + "connection initialized.")
|
||||
while self.running:
|
||||
data = self.receive_aes()
|
||||
header = self.extract_header(data)
|
||||
print(header)
|
||||
print(data)
|
||||
print(self.rsa_client)
|
||||
if header[b"type"] == b"register_client":
|
||||
self.register_client()
|
||||
elif header[b"type"] == b"getUsers":
|
||||
self.send_users()
|
||||
self.client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
clients = []
|
||||
server = ServerThread(main_socket, ip=HOST, port=PORT)
|
||||
while True:
|
||||
main_socket.listen(1) # Waiting for incoming connections
|
||||
client_socket, (ip, PORT) = main_socket.accept()
|
||||
newClient = ClientThread(client_socket, ip, PORT)
|
||||
newClient = ClientThread(client_socket, ip, PORT, server)
|
||||
newClient.start()
|
||||
clients.append(newClient)
|
||||
|
57
server/private.pem
Normal file
57
server/private.pem
Normal file
@ -0,0 +1,57 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
15
server/public.pem
Normal file
15
server/public.pem
Normal file
@ -0,0 +1,15 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIICYjANBgkqhkiG9w0BAQEFAAOCAk8AMIICSgKCAkEAlmEl3vGDG4qxqPvO98zC
|
||||
pDbrFrNeTbwThiqCnuu0Cp5h/ejNeSChnRkmyOffMtvmBCmCJNw0vR9/Cpatzx9T
|
||||
XekXUWRjXbUfR1ECQ2Fo0xqS3GE58F8HYnhra9+i3xJXSJRpk7P1FaKGakie0GGo
|
||||
MCcImGZyWuSjNbUa4hj+I+Nlgf3rwQfll/06Wy7YLWXCXnNCTnirVYJooPphy3Qq
|
||||
tNj+clwCvoY8F7Tz5PDfffiDPjxb+uOWwtfi0LecL5YqZC8aed/70WcujItkGQ2Y
|
||||
hReYV+jsXvj1DTA0VB/RdrzRYeTNqYSoS7t8+cmWM27syEPb+11JLQZB4kPUB4yY
|
||||
Ffk/a1ffkmEZYtqRdbndM20Loksr3C/jHRrmqfCjRVmL2wHK64wUUbGLKcSMLHkA
|
||||
UR1HaeZ+PJ2qXX7ed4MBDRQDaMM7JGrkwz3hyBq2fblUT+OarHnlwRDvLL+XlACr
|
||||
NJ7yvnigwCkx7MVwakhr0yWc0o9QHEmA2DnibE4JCrNfyAwV+hKs9p+F0XjbbutO
|
||||
USXFxKdImKzf4NG1eNtMKFeIKZgtzm/JVhvlSC4p6ko+szBd89A11K1oHKRVNC64
|
||||
rnNH89o2qdT495HRfnFoEHgxA0nQH85QlCajOT0R122ha5ksJxXgj+HzTXiKa4Lt
|
||||
TXy5kWWkYGMGxK6Xmxn32QPZHCgZA1L99uvZjr1hgkqxrI8p1wBPABN3vdr1CLwq
|
||||
4kp0g+BOsFAb7X9rWn6xW9wTY8QmFW9Ze+K3Fn7aYg41AgMBAAE=
|
||||
-----END PUBLIC KEY-----
|
Loading…
Reference in New Issue
Block a user