def setUpClass(cls): cls.public_ip = '123.45.67.89' cls.port = 12345 cls.own_addr = (cls.public_ip, cls.port) cls.addr1 = ('132.54.76.98', 54321) cls.addr2 = ('231.76.45.89', 15243) cls.privkey1_hex = '71d1054068b224a4d9013104881dc7f46c6fec9a618f4574ae21059723e6c4f8' cls.privkey1 = public.PrivateKey(cls.privkey1_hex, encoder=encoding.HexEncoder) cls.pubkey1 = cls.privkey1.public_key cls.pubkey1_bytes = cls.pubkey1.encode(encoder=encoding.RawEncoder) cls.privkey2_hex = '4c107b7844368d0fb608f3d91ae194f2d62c7ff91b713e5b05c279e8b7fc61b3' cls.privkey2 = public.PrivateKey(cls.privkey2_hex, encoder=encoding.HexEncoder) cls.pubkey2 = cls.privkey2.public_key cls.pubkey2_bytes = cls.pubkey2.encode(encoder=encoding.RawEncoder) cls.remote_crypto_box = public.Box(cls.privkey2, cls.pubkey1) cls.nonce = utils.random(cls.remote_crypto_box.NONCE_SIZE) cls.local_crypto_box = public.Box(cls.privkey1, cls.pubkey2) cls.privkey3_hex = '40246691a4362a220606dd302b03e992b5b5fe21026377fa56c9fe3f5afbcbd0' cls.privkey3 = public.PrivateKey(cls.privkey3_hex, encoder=encoding.HexEncoder) cls.pubkey3 = cls.privkey3.public_key cls.pubkey3_bytes = cls.pubkey3.encode(encoder=encoding.RawEncoder) cls.other_crypto_box = public.Box(cls.privkey3, cls.pubkey1)
def get(self, request): gks = db.get('gks') stream = server.getps(db.get('gkfp')) gke = db.get('gke') box = pubfool.Box(gke, gke.public_key) hits = list() for post in stream: valid = True # Valid signature, will be flipped to False on error try: post = json.loads(box.decrypt(debase(post['encrypted']), debase(post['nonce'])).decode()) print(post) except Exception: # Multiple exceptions can happen which can show malformed message, such as non-UTF8 characters, bad JSON, bad nonce, bad ciphertext, etc. just miss and move on continue try: gks.verify_key.verify(post['msg'].encode(), debase(post['sig'])) uks = signfool.VerifyKey(post['gangsta']['edpub'].encode(), encoder=b64) uks.verify(post['msg'].encode(), debase(post['usig'])) post['KH'] = base64.b64encode(whirlpool(post['gangsta']['edpub'].encode()+post['gangsta']['cvpub'].encode())).decode() except BadSignatureError: valid = False except Exception: continue if valid: hits.append(post) pass pass hits.reverse() ctx = dict(hits=hits) return render(request, 'stream.get.html', ctx)
def decryptDict(dct, signingPrivateKey, realPrivateKey, realPublicKey): """decrypt all values in a dictionary Assumes all values in a dictionary are base64ed encrypted with realPublicKey, and signed with signingPrivateKey, and decrypt them with realPrivateKey. If realPrivateKey and realPublicKey do not correspond to each other, or any value in the dictionary is not signed and encrypted correctly, an exception is raised. :param dct: encrypted dictionary :type dct: dictionary with string values and keys :param signingPrivateKey: base64 encoded NaCl private key :type signingPrivateKey: string :param realPrivateKey: base64 encoded NaCl private key :type realPrivateKey: string :param realPublicKey: base64 encoded NaCl private key :type realPublicKey: string :rtype: dictionary with string values and keys """ signingPrivateKey = npublic.PrivateKey( base64.decodestring(signingPrivateKey)) signingPublicKey = signingPrivateKey.public_key realPrivateKey = npublic.PrivateKey(base64.decodestring(realPrivateKey)) realPublicKey = npublic.PublicKey(base64.decodestring(realPublicKey)) if realPrivateKey.public_key.encode() != realPublicKey.encode(): raise ValueError('private key and public key do not match', realPrivateKey.public_key, realPublicKey) box = npublic.Box(realPrivateKey, signingPublicKey) ret = {} for key, value in six.iteritems(dct): decodedValue = base64.decodestring(value) decryptedValue = box.decrypt(decodedValue) ret[key] = decryptedValue return ret
def del_(addr, fil): pkr = requests.get(addr + "/pk", verify=False) sk = pkr.json()["key"] mypub, mysec, nospam = read_tox(fil) check = _compute_checksum(mypub + nospam) print("kotone: Deleting {0} from server.".format(mypub, check)) inner = json.dumps({ "public_key": mypub, # Public key "timestamp": int(time.time()) # Timestamp }) k = crypto.PrivateKey(mysec, crypto_encode.HexEncoder) nonce = os.urandom(crypto.Box.NONCE_SIZE) b = crypto.Box(k, crypto.PublicKey(sk, crypto_encode.HexEncoder)) msg = b.encrypt(inner.encode("utf8"), nonce, crypto_encode.Base64Encoder) payload = json.dumps({ "action": 2, "public_key": mypub, "encrypted": msg.ciphertext.decode("utf8"), "nonce": crypto_encode.Base64Encoder.encode(nonce).decode("utf8") }) resp = requests.post(addr + "/api", data=payload, verify=False) a = resp.json() if a["c"] == 0: print("\033[32mOK:\033[0m record deleted. " "It may take a minute to update.") else: print("\033[32mFailed:\033[0m {0}".format(a["c"]))
def _encrypted_payload_prologue(self, envelope): if not self._typecheck_dict(envelope, {"public_key": str, "nonce": str, "encrypted": str}): self.set_status(400) self.json_payload(error_codes.ERROR_BAD_PAYLOAD) LOGGER.warn("Unable to read payload") return try: other_key = public.PublicKey(envelope["public_key"], KEY_ENC) except nacl.exceptions.CryptoError: LOGGER.warn("did fail req because other pk was bad") self.set_status(400) self.json_payload(error_codes.ERROR_BAD_PAYLOAD) return box = public.Box(self.settings["crypto_core"].pkey, other_key) try: nonce = nacl.encoding.Base64Encoder.decode(envelope["nonce"]) ciphertext = nacl.encoding.Base64Encoder.decode(envelope["encrypted"]) clear = box.decrypt(ciphertext, nonce, nacl.encoding.RawEncoder) except (ValueError, TypeError, nacl.exceptions.CryptoError): LOGGER.warn("did fail req because a base64 value was bad") self.set_status(400) self.json_payload(error_codes.ERROR_BAD_PAYLOAD) return try: clear = json.loads(clear.decode("utf8")) except (UnicodeDecodeError, TypeError): LOGGER.warn("did fail req because inner json decode failed") self.set_status(400) self.json_payload(error_codes.ERROR_BAD_PAYLOAD) return return clear
def post(self, request): form = PF(request.POST, request.FILES) if not form.is_valid(): raise RuntimeError("Invalid HTML form submitted") message = form.cleaned_data['message'] name = form.cleaned_data['name'] image = form.cleaned_data['image'] if message == 'none': raise KeyError("Message doesn't exist") gks = db.get('gks') gke = db.get('gke') sig = gks.sign(message.encode()) usig = db.get("user-edkeys").sign(message.encode()) box = pubfool.Box(gke, gke.public_key) gangsta = { 'name': name, 'edpub': db.get("user-edkeys").verify_key.encode(encoder=b64).decode(), 'cvpub': db.get("user-cvkeys").public_key.encode(encoder=b64).decode(), } payload = { 'msg': sig.message.decode(), 'sig': base64.b64encode(sig.signature).decode(), 'usig': base64.b64encode(usig.signature).decode(), 'gangsta': gangsta, } if image is not None: buf = image.read() payload ['image'] = base64.b64encode(buf).decode() else: payload['image'] = None nonce = os.urandom(24) payload = json.dumps(payload) payload = box.encrypt(plaintext=payload.encode(), nonce=nonce) realpayload = { 'key': db.get('gkfp'), 'encrypted': base64.b64encode(payload._ciphertext).decode(), 'nonce': base64.b64encode(nonce).decode(), } server.HTTP().POST("/new/post", realpayload) ctx = dict(sig=base64.b64encode(sig.signature).decode()) return render(request, "newpost.post.html", ctx)
def encrypt(value, signingPrivateKey, realPublicKey): """encrypt and sign a value, and base64-encode the result :param value: a secret :type value: string :param signingPrivateKey: base64 encoded NaCl private key :type signingPrivateKey: string :param realPublicKey: base64 encoded NaCl private key :type realPublicKey: string :rtype: string """ signingPrivateKey = npublic.PrivateKey( base64.decodestring(signingPrivateKey)) realPublicKey = npublic.PublicKey(base64.decodestring(realPublicKey)) box = npublic.Box(signingPrivateKey, realPublicKey) nonce = nutils.random(npublic.Box.NONCE_SIZE) encrypted = box.encrypt(value, nonce) encoded = base64.encodestring(encrypted) oneline = ''.join(encoded.splitlines()) return oneline
def r(addr): pkr = requests.get(addr + "/pk", verify=False) sk = pkr.json()["key"] k = crypto.PrivateKey.generate() mypub = k.public_key.encode( crypto_encode.HexEncoder).upper().decode("ascii") nospam = "00000000" check = _compute_checksum(mypub + nospam) print("kotone: Deleting {0} from server.".format(mypub, check)) inner = json.dumps({ "tox_id": mypub + nospam + check, "timestamp": int(time.time()), "name": "test-" + str(random.randint(0, 999999999)), "bio": "top test :^)", "privacy": 1, }) nonce = os.urandom(crypto.Box.NONCE_SIZE) b = crypto.Box(k, crypto.PublicKey(sk, crypto_encode.HexEncoder)) msg = b.encrypt(inner.encode("utf8"), nonce, crypto_encode.Base64Encoder) payload = json.dumps({ "action": 1, "public_key": mypub, "encrypted": msg.ciphertext.decode("utf8"), "nonce": crypto_encode.Base64Encoder.encode(nonce).decode("utf8") }) resp = requests.post(addr + "/api", data=payload, verify=False) print(resp.text) a = resp.json() if a["c"] == 0: print("\033[32mOK:\033[0m ") else: print("\033[32mFailed:\033[0m {0}".format(a["c"]))
def receive_packet(self, rudp_packet, from_addr): """ Process received packet and update connection state. Called by protocol when a packet arrives for this connection. If the packet is a SYN, setup encryption infrastructure; if not, ensure packet is successfully decrypted before further processing. Silently drop malicious packages. Args: rudp_packet: Received packet.Packet. from_addr: Sender's address as Tuple (ip, port). """ if rudp_packet.syn and self._crypto_box is None: # Try to create a crypto box for this connection, by # combining remote public key and local private key. try: remote_public_key = public.PublicKey( rudp_packet.payload, encoder=encoding.RawEncoder) self._crypto_box = public.Box(self._private_key, remote_public_key) except (exceptions.CryptoError, ValueError): pass else: self._remote_public_key = rudp_packet.payload super(CryptoConnection, self).receive_packet(rudp_packet, from_addr) elif not rudp_packet.syn and self._crypto_box is not None: try: rudp_packet.payload = self._crypto_box.decrypt( rudp_packet.payload) except (exceptions.CryptoError, exceptions.BadSignatureError, ValueError): pass else: super(CryptoConnection, self).receive_packet(rudp_packet, from_addr)
def push(addr, name, bio, fil): pkr = requests.get(addr + "/pk", verify=False) sk = pkr.json()["key"] mypub, mysec, nospam = read_tox(fil) check = _compute_checksum(mypub + nospam) print("kotone: Publishing {0}/{1} to server.".format(mypub, check)) inner = json.dumps({ "tox_id": mypub + nospam + check, # Public key + checksum "name": name, # Desired name "privacy": 1, # Privacy level (1 or higher appears in FindFriends) "bio": bio.strip(), # Bio (quote displayed on web) "timestamp": int(time.time()) # A timestamp near the server's time }) k = crypto.PrivateKey(mysec, crypto_encode.HexEncoder) nonce = os.urandom(crypto.Box.NONCE_SIZE) b = crypto.Box(k, crypto.PublicKey(sk, crypto_encode.HexEncoder)) msg = b.encrypt(inner.encode("utf8"), nonce, crypto_encode.Base64Encoder) payload = json.dumps({ "action": 1, # Action number "public_key": mypub, # Public key "encrypted": msg.ciphertext.decode("utf8"), # Encrypted payload base64 (above) "nonce": crypto_encode.Base64Encoder.encode(nonce).decode("utf8") # b64 }) resp = requests.post(addr + "/api", data=payload, verify=False) a = resp.json() if a["c"] == 0: print("\033[32mOK:\033[0m record successfully published.") print("Password is '{0}'.".format(a["password"])) else: print("\033[32mFailed:\033[0m {0}".format(a["c"]))
def dsrec_encrypt_key(self, client, nonce, msg): box = public.Box(self.pkey, public.PublicKey(client)) by = box.encrypt(msg, nonce) return by[24:]
def dsrep_decode_name(self, client, nonce, pl): box = public.Box(self.pkey, public.PublicKey(client)) by = box.decrypt(pl, nonce) return by