public CryptoBox(Streamable data, byte[] K) throws IOException { this(Encode.bytes(data), K); }
@Override public void write(OutputStream out) throws IOException { // magic Encode.int32(MAGIC, out); // ASCII string identifying the packet content, NULL padded (non-NULL padding results in packet rejected) String command = payload.getCommand().name().toLowerCase(); out.write(command.getBytes("ASCII")); for (int i = command.length(); i < 12; i++) { out.write('\0'); } byte[] payloadBytes = Encode.bytes(payload); // Length of payload in number of bytes. Because of other restrictions, there is no reason why this length would // ever be larger than 1600003 bytes. Some clients include a sanity-check to avoid processing messages which are // larger than this. Encode.int32(payloadBytes.length, out); // checksum try { out.write(getChecksum(payloadBytes)); } catch (GeneralSecurityException e) { throw new ApplicationException(e); } // message payload out.write(payloadBytes); }
byte[] payloadBytes = Encode.bytes(payload);
public CryptoBox(Streamable data, ECPoint K) throws IOException { curveType = 0x02CA; // 1. The destination public key is called K. // 2. Generate 16 random bytes using a secure random number generator. Call them IV. initializationVector = Security.randomBytes(16); // 3. Generate a new random EC key pair with private key called r and public key called R. byte[] r = Security.randomBytes(PRIVATE_KEY_SIZE); R = Security.createPublicKey(r); // 4. Do an EC point multiply with public key K and private key r. This gives you public key P. ECPoint P = K.multiply(Security.keyToBigInt(r)).normalize(); byte[] X = P.getXCoord().getEncoded(); // 5. Use the X component of public key P and calculate the SHA512 hash H. byte[] H = Security.sha512(X); // 6. The first 32 bytes of H are called key_e and the last 32 bytes are called key_m. byte[] key_e = Arrays.copyOfRange(H, 0, 32); byte[] key_m = Arrays.copyOfRange(H, 32, 64); // 7. Pad the input text to a multiple of 16 bytes, in accordance to PKCS7. // 8. Encrypt the data with AES-256-CBC, using IV as initialization vector, key_e as encryption key and the padded input text as payload. Call the output cipher text. encrypted = crypt(true, Encode.bytes(data), key_e); // 9. Calculate a 32 byte MAC with HMACSHA256, using key_m as salt and IV + R + cipher text as data. Call the output MAC. mac = calculateMac(key_m); // The resulting data is: IV + R + cipher text + MAC }
if (type == Type.MSG) { if (to.has(Feature.DOES_ACK) && getAckMessage() != null) { Encode.varBytes(Encode.bytes(getAckMessage()), buffer); } else { Encode.varInt(0, buffer);