/** * Reconstruct key from got byte array. Calls when we receive session key from remote party. * @param key is byte array with packed key. */ public void reconstructSessionKey(byte[] key) throws EncryptionError { sessionKey = new SymmetricKey(key); }
@Test public void bytesRange() throws Exception { SymmetricKey k = new SymmetricKey(); byte[] src = new byte[4]; src[0] = (byte) 255; src[1] = (byte) 254; src[2] = (byte) 253; src[3] = (byte) 252; assertThat(k.decrypt(k.encrypt(src)), equalTo(src)); }
/** * We have received {@link PacketTypes#ACK} packet. Need to stop retransmitting of ack-ed packet. * @param packet received {@link Packet} */ private void onReceiveAck(Packet packet) throws EncryptionError, SymmetricKey.AuthenticationFailed { report(logLabel, ()->"received ack from " + packet.senderNodeId, VerboseLevel.DETAILED); Session session = getOrCreateSession(packet.senderNodeId); if (session != null) { if (session.state.get() == Session.STATE_EXCHANGING) { Integer ackPacketId = Boss.load(new SymmetricKey(session.sessionKey.getKey()).etaDecrypt(packet.payload)); session.removePacketFromRetransmitMap(ackPacketId); } } }
private void createSessionKey() throws EncryptionError { if (sessionKey == null) { sessionKey = new SymmetricKey(); Binder data = Binder.fromKeysValues( "sk", sessionKey.pack() ); encryptedAnswer = publicKey.encrypt(Boss.pack(data)); } }
/** * ACK packets are used only for respond to DATA packets. Retransmission of handshake's packet types stops on each * next handshake step. But last step need to be ACK-ed. For this used {@link PacketTypes#SESSION_ACK} packet. * @param session is {@link Session} in which sending is. * @throws EncryptionError */ private void sendSessionAck(Session session) throws EncryptionError { report(logLabel, ()->"send session_ack to "+session.remoteNodeInfo.getNumber(), VerboseLevel.BASE); Packet packet = new Packet(0, myNodeInfo.getNumber(), session.remoteNodeInfo.getNumber(), PacketTypes.SESSION_ACK, new SymmetricKey(session.sessionKey.getKey()).etaEncrypt(Do.randomBytes(32))); sendPacket(session.remoteNodeInfo, packet); }
@Test public void etaEncrypt() throws Exception { SymmetricKey k = new SymmetricKey(); byte[] plainText = "Hello, world!".getBytes(); byte[] cipherText = k.etaEncrypt(plainText); // Bytes.dump(cipherText); assertEquals(16 + 32 + plainText.length, cipherText.length); byte[] decryptedText = k.etaDecrypt(cipherText); assertArrayEquals(plainText, decryptedText); exception.expect(SymmetricKey.AuthenticationFailed.class); cipherText[19] += 1; k.etaDecrypt(cipherText); }
throw new IllegalStateException("missing encryption keys"); SymmetricKey mainKey = new SymmetricKey(); byte[] packedMainKey = mainKey.pack(); data.put("data", mainKey.etaEncrypt(packedPrivate));
("5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843"); SymmetricKey k = new SymmetricKey(key); byte[] data = k.etaSign(source); valid = Hex.decode("82558a389a443c0ea4cc819899f2083a" + "85f0faa3e578f8077a2e3ff46729665b"); k.setKey(key); data = k.etaSign(source); data = Arrays.copyOfRange(data, data.length - 32, data.length); assertEquals(valid.length, data.length); assertArrayEquals(valid, data); k.setKey(Hex.decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + valid = Hex.decode("60e431591ee0b67f0d8a26aacbf5b77f\n" + " 8e0bc6213728c5140546040f0ee37f54"); data = k.etaSign(source); data = Arrays.copyOfRange(data, data.length - 32, data.length); assertEquals(valid.length, data.length);
byte[] encryptedKey = b.getBinary("key"); try { SymmetricKey sk = new SymmetricKey(k.decrypt(encryptedKey)); privateData = Boss.unpack(sk.etaDecrypt(encryptedData)); break outer; } catch (Exception e) {
public Binder command(Binder params) throws ClientError, EncryptionError { // decrypt params and execute command Binder result = null; try { result = Binder.fromKeysValues( "result", executeAuthenticatedCommand( Boss.unpack( sessionKey.decrypt(params.getBinaryOrThrow("params")) ) ) ); } catch (Exception e) { ErrorRecord r = (e instanceof ClientError) ? ((ClientError) e).getErrorRecord() : new ErrorRecord(Errors.COMMAND_FAILED, "", e.getMessage()); result = Binder.fromKeysValues( "error", r ); } // encrypt and return result return Binder.fromKeysValues( "result", sessionKey.encrypt(Boss.pack(result)) ); }
@Test public void symmetricKeyMustHaveRightInfo() { SymmetricKey k = new SymmetricKey(); KeyInfo h = k.info(); assertEquals(KeyInfo.Algorythm.AES256, h.getAlgorythm()); assertEquals(32, h.getKeyLength()); assertEquals(KeyInfo.PRF.None, h.getPRF()); }
@Test public void deriveKey() throws Exception { KeyInfo h1 = new KeyInfo(KeyInfo.PRF.HMAC_SHA256, 4096, null, null); KeyInfo h2 = new KeyInfo(h1.pack()); assertArrayEquals(h1.getSalt(), h2.getSalt()); assertArrayEquals("attesta".getBytes(), h2.getSalt()); SymmetricKey k = h1.derivePassword("elegance"); byte[] k1 = PBKDF2.derive(Sha256.class, "elegance", "attesta".getBytes(), 4096, 32); assertArrayEquals(k1, k.getKey()); assertEquals(h1, k.info()); }
@Override public void initialize(Direction direction, SymmetricKey key) { this.key = key.getKey(); if (initialized()) { CipherParameters params = new KeyParameter(this.key); aesEngine.init(direction == Direction.ENCRYPT, params); } }
@Override public void send(Map<String, Object> data) throws IOException { checkConnected(); byte[] packed = mySessionKey.etaEncrypt(Boss.pack(data)); if (!connection.isClosed()) connection.sendParams("block", packed); else throw new EOFException("connection closed"); }
private Object decryptBlock(Command command) throws EncryptionError { try { synchronized (remoteSessionKey) { Bytes ciphertext = command.getParam(0); if (ciphertext == null) { throw new IllegalStateException("missing block data"); } Binder plain = Boss.unpack(remoteSessionKey.etaDecrypt(ciphertext.toArray())); inputQueue.put(plain); } } catch (SymmetricKey.AuthenticationFailed authenticationFailed) { throw new EncryptionError("authentication failed on bitrusted block"); } catch (InterruptedException e) { Thread.interrupted(); } catch (Exception e) { log.wtf("failed to process block", e); e.printStackTrace(); } return null; }
public byte[] packWithPassword(String password) throws EncryptionError { byte[] packedKey = pack(); byte[] salt = getClass().getCanonicalName().getBytes(); int rounds = getKDFRounds(); KeyInfo.PRF function = KeyInfo.PRF.HMAC_SHA256; SymmetricKey key = new KeyInfo(function, rounds, salt, null) .derivePassword(password); byte[] packedEncryptedKey = key.encrypt(packedKey); return Boss.dumpToArray(new Object[]{ 2, rounds, salt, function.name(), packedEncryptedKey, new Crc32().update(packedKey).digest() }); }
public static PrivateKey unpackWithPassword(byte[] packedBinary, String password) throws EncryptionError { List params = Boss.load(packedBinary); if ((Integer) params.get(0) == 0) { return new PrivateKey(packedBinary); } else if ((Integer) params.get(0) == 1) { throw new EncryptionError("the key is public, not private"); } else if ((Integer) params.get(0) == 2) { try { int rounds = (int) params.get(1); Bytes salt = (Bytes) params.get(2); String function = (String) params.get(3); Bytes packedEncryptedKey = (Bytes) params.get(4); Bytes digest = (Bytes) params.get(5); SymmetricKey key = new KeyInfo(KeyInfo.PRF.valueOf(function), rounds, salt.getData(), null) .derivePassword(password); byte[] packedKey = key.decrypt(packedEncryptedKey.getData()); byte[] resDigest = new Crc32().update(packedKey).digest(); if (!digest.equals(new Bytes(resDigest))) { throw new PasswordProtectedException("wrong password"); } return new PrivateKey(packedKey); } catch (Exception e) { if (e instanceof PasswordProtectedException) throw e; throw new EncryptionError("failed to parse password protected private key", e); } } else { throw new EncryptionError("Bad or unknown private key type"); } }
public SymmetricKey(byte[] key, KeyInfo keyInfo) { setKey(key); this.keyInfo = keyInfo; }
public Binder asBinder() { return Binder.fromKeysValues( "connectMessage", getConnectMessage(), // "privateKey", privateKey.pack(), "sessionKey", getSessionKey().pack(), "sessionId", getSessionId() // "nodePublicKey", nodePublicKey.pack() ); }
public static SymmetricKey fromPassword(String password, int rounds) { return fromPassword(password, rounds, null); }