/** * Sign the data with a given key. * * @param key is {@link PrivateKey} to sign with. * @param data to be sign with key. * @param savePublicKey if true key will stored in the {@link ExtendedSignature}. * * @return binary signature */ static public byte[] sign(PrivateKey key, byte[] data, boolean savePublicKey) { try { byte[] targetSignature = ExtendedSignature.createTargetSignature(key.getPublicKey(),data,savePublicKey); return ExtendedSignature.of(targetSignature, key.sign(targetSignature, HashType.SHA512), key.sign(targetSignature, HashType.SHA3_384)); } catch (EncryptionError e) { throw new RuntimeException("signature failed", e); } }
byte[] receipt = callbackKey.sign(id.getDigest(), HashType.SHA512);
try { byte[] data = Bytes.random(128).getData(); byte[] signature = privateKey.sign(data, HashType.SHA512); if(!publicKey.verify(data,signature,HashType.SHA512)) { errorsCount.incrementAndGet(); try { byte[] data = Bytes.random(128).getData(); byte[] signature = privateKey.sign(data, HashType.SHA3_384); if(!publicKey.verify(data,signature,HashType.SHA3_384)) { errorsCount.incrementAndGet();
byte[] packed = Boss.pack(data); byte[] encrypted = new PublicKey(session.remoteNodeInfo.getPublicKey().pack()).encrypt(packed); byte[] sign = new PrivateKey(ownPrivateKey.pack()).sign(encrypted, HashType.SHA512);
/** * Each adapter will try to send blocks until have got special {@link Packet} with type {@link PacketTypes#ACK}, * that means receiver have got block. So when we got block, but something went wrong - call this method. Note that * for success blocks needs to call {@link UDPAdapter#sendAck(SessionReader, Integer)} * @param nodeNumber node id in which sending is * @param packetId is id of block we have got. */ private void sendNack(Integer nodeNumber, Integer packetId) { try { NodeInfo destination = netConfig.getInfo(nodeNumber); if (destination != null) { report(logLabel, ()->"send nack to "+nodeNumber, VerboseLevel.DETAILED); byte[] randomSeed = Do.randomBytes(64); byte[] data = Boss.dumpToArray(Arrays.asList(packetId, randomSeed)); byte[] sign = new PrivateKey(ownPrivateKey.pack()).sign(data, HashType.SHA512); byte[] payload = Boss.dumpToArray(Arrays.asList(data, sign)); Packet packet = new Packet(0, myNodeInfo.getNumber(), nodeNumber, PacketTypes.NACK, payload); sendPacket(destination, packet); } } catch (EncryptionError e) { callErrorCallbacks("(sendNack) can't send NACK, EncryptionError: " + e); } }
private Object onHello(Binder params) throws IOException { // Checking protocol and version if (!params.getStringOrThrow("protocol").equals("bitrusted")) throw new IOException("unsupported protocol, needs bitrusted'"); if (params.getIntOrThrow("version") > MY_VERSION) throw new IOException("unsupported protocol version, needs <= " + MY_VERSION); // checking parameters byte[] nonce = params.getBinaryOrThrow("nonce"); setRemoteKey(params.getBinaryOrThrow("public_key")); remoteSessionKey = new SymmetricKey(params.getBinaryOrThrow("session_key")); // We intentionally do not use capsule here to improve network speed byte[] result = Boss.pack(Binder.fromKeysValues( "session_key", mySessionKey.pack(), "nonce", nonce) ); result = remoteKey.encrypt(result); byte[] signature = myKey.sign(result, HashType.SHA256); ready.fire(null); // log.d(toString() + " returning hello"); return Binder.fromKeysValues( "data", result, "signature", signature, "public_key", myKey.getPublicKey().pack() ); }
Binder getToken(Binder data) { // Check the answer is properly signed byte[] signedAnswer = data.getBinaryOrThrow("data"); try { if (publicKey.verify(signedAnswer, data.getBinaryOrThrow("signature"), HashType.SHA512)) { Binder params = Boss.unpack(signedAnswer); // now we can check the results if (!Arrays.equals(params.getBinaryOrThrow("server_nonce"), serverNonce)) addError(Errors.BAD_VALUE, "server_nonce", "does not match"); else { // Nonce is ok, we can return session token createSessionKey(); Binder result = Binder.fromKeysValues( "client_nonce", params.getBinaryOrThrow("client_nonce"), "encrypted_token", encryptedAnswer ); byte[] packed = Boss.pack(result); return Binder.fromKeysValues( "data", packed, "signature", myKey.sign(packed, HashType.SHA512) ); } } } catch (Exception e) { addError(Errors.BAD_VALUE, "signed_data", "wrong or tampered data block:" + e.getMessage()); } return null; }
/** * When someone send us {@link PacketTypes#HELLO} typed {@link UDPAdapter.Packet}, * we should respond with {@link PacketTypes#WELCOME}. * @param sessionReader is {@link UDPAdapter.SessionReader} in which sending is. */ private void sendWelcome(SessionReader sessionReader) { try { report(logLabel, () -> "send welcome to " + sessionReader.remoteNodeInfo.getNumber(), VerboseLevel.BASE); byte[] data = sessionReader.localNonce; byte[] sign = new PrivateKey(ownPrivateKey.pack()).sign(data, HashType.SHA512); byte[] payload = Boss.dumpToArray(Arrays.asList(data, sign)); Packet packet = new Packet(getNextPacketId(), myNodeInfo.getNumber(), sessionReader.remoteNodeInfo.getNumber(), PacketTypes.WELCOME, payload); sendPacket(sessionReader.remoteNodeInfo, packet); sessionReader.removeHandshakePacketsFromRetransmitMap(); sessionReader.addPacketToRetransmitMap(packet.packetId, packet, sessionReader.localNonce); } catch (EncryptionError e) { callErrorCallbacks("(sendWelcome) EncryptionError: " + e); } }
/** * Someone who sent {@link PacketTypes#HELLO} typed {@link Packet}, * send us new KEY_REQ typed {@link Packet} - if all is ok we send session keys to. * SESSION's payload is more than 512 bytes, so used two parts here. * From now we ready to data exchange. * @param sessionReader is {@link SessionReader} in which sending is. */ private void sendSessionKey(SessionReader sessionReader) throws EncryptionError { report(logLabel, ()->"send session_key to "+sessionReader.remoteNodeInfo.getNumber(), VerboseLevel.BASE); List data = Arrays.asList(sessionReader.sessionKey.getKey(), sessionReader.remoteNonce); byte[] packed = Boss.pack(data); byte[] encrypted = new PublicKey(sessionReader.remoteNodeInfo.getPublicKey().pack()).encrypt(packed); byte[] sign = new PrivateKey(ownPrivateKey.pack()).sign(encrypted, HashType.SHA512); Packet packet1 = new Packet(getNextPacketId(), myNodeInfo.getNumber(), sessionReader.remoteNodeInfo.getNumber(), PacketTypes.SESSION_PART1, encrypted); Packet packet2 = new Packet(getNextPacketId(), myNodeInfo.getNumber(), sessionReader.remoteNodeInfo.getNumber(), PacketTypes.SESSION_PART2, sign); sendPacket(sessionReader.remoteNodeInfo, packet1); sendPacket(sessionReader.remoteNodeInfo, packet2); sessionReader.addPacketToRetransmitMap(packet1.packetId, packet1, encrypted); sessionReader.addPacketToRetransmitMap(packet2.packetId, packet2, sign); }
"signature", privateKey.sign(data, HashType.SHA512), "data", data, "session_id", this.session.getSessionId()