Example usage for org.bouncycastle.util Arrays copyOfRange

List of usage examples for org.bouncycastle.util Arrays copyOfRange

Introduction

In this page you can find the example usage for org.bouncycastle.util Arrays copyOfRange.

Prototype

public static BigInteger[] copyOfRange(BigInteger[] original, int from, int to) 

Source Link

Usage

From source file:com.github.horrorho.inflatabledonkey.chunk.engine.ChunkKeys.java

License:Open Source License

Optional<byte[]> type2(byte[] chunkEncryptionKey, byte[] keyEncryptionKey) {
    if (chunkEncryptionKey.length != 0x19) {
        logger.warn("-- type2() - bad chunk encryption key length: 0x:{}", Hex.toHexString(chunkEncryptionKey));
        return Optional.empty();
    }/*from  www .java  2 s.co m*/
    byte[] wrappedKey = Arrays.copyOfRange(chunkEncryptionKey, 0x01, 0x19);
    return RFC3394Wrap.unwrapAES(keyEncryptionKey, wrappedKey).map(u -> {
        byte[] k = new byte[0x11];
        k[0] = 0x01;
        System.arraycopy(u, 0, k, 1, u.length);
        return k;
    });
}

From source file:com.joyent.manta.serialization.EncryptedMultipartUploaSerializationHelper.java

License:Open Source License

/**
 * Decrypts and deserializes the specified binary blob.
 *
 * @param serializedData data to decrypt and deserialize
 * @return an upload object//w ww.ja  v  a 2s.c  o  m
 */
@SuppressWarnings("unchecked")
public EncryptedMultipartUpload<WRAPPED> deserialize(final byte[] serializedData) {
    final byte[] iv = Arrays.copyOf(serializedData, cipherDetails.getIVLengthInBytes());

    if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("Reading IV: {}", Hex.toHexString(iv));
    }

    final Cipher cipher = cipherDetails.getCipher();
    try {
        cipher.init(Cipher.DECRYPT_MODE, secretKey, cipherDetails.getEncryptionParameterSpec(iv));
    } catch (GeneralSecurityException e) {
        String msg = String.format("Unable to initialize cipher [%s]", cipherDetails.getCipherId());
        throw new MantaClientEncryptionException(msg, e);
    }

    final byte[] cipherText;

    if (cipherDetails.isAEADCipher()) {
        cipherText = extractCipherText(serializedData, iv.length, null);
    } else {
        final byte[] hmacIdBytes = Arrays.copyOfRange(serializedData,
                serializedData.length - CIPHER_ID_SIZE_BYTES, serializedData.length);
        final String hmacId = new String(hmacIdBytes, StandardCharsets.US_ASCII).trim();

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Verifying checksum with [{}]", hmacId);
        }

        final Supplier<HMac> hmacSupplier = SupportedHmacsLookupMap.INSTANCE.get(hmacId);

        if (hmacSupplier == null) {
            String msg = String.format("Unknown HMAC: [%s]", hmacId);
            throw new MantaClientEncryptionException(msg);
        }

        final HMac hmac = hmacSupplier.get();
        final int hmacLength = hmac.getMacSize();

        cipherText = extractCipherText(serializedData, iv.length, hmacLength);

        hmac.update(iv, 0, iv.length);
        hmac.update(cipherText, 0, cipherText.length);
        final byte[] calculated = new byte[hmacLength];
        hmac.doFinal(calculated, 0);

        final byte[] expected = Arrays.copyOfRange(serializedData,
                serializedData.length - hmacLength - CIPHER_ID_SIZE_BYTES,
                serializedData.length - CIPHER_ID_SIZE_BYTES);

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Expected HMAC:   {}", Hex.toHexString(expected));
            LOGGER.debug("Calculated HMAC: {}", Hex.toHexString(calculated));
        }

        if (!Arrays.areEqual(calculated, expected)) {
            String msg = "Serialization data ciphertext failed " + "cryptographic authentication";
            MantaClientEncryptionCiphertextAuthenticationException e = new MantaClientEncryptionCiphertextAuthenticationException(
                    msg);
            e.setContextValue("expected", Hex.toHexString(expected));
            e.setContextValue("calculated", Hex.toHexString(calculated));
            throw e;
        }
    }

    final byte[] plaintext;
    try {
        plaintext = cipher.doFinal(cipherText);
    } catch (GeneralSecurityException e) {
        String msg = "Error decrypting serialized object data";
        throw new MantaClientEncryptionException(msg, e);
    }

    final EncryptedMultipartUpload<WRAPPED> upload;

    try (Input input = new Input(plaintext)) {
        final int serializationVersion = input.readVarInt(true);

        if (serializationVersion != ENCRYPTED_MULTIPART_UPLOAD_SERIALIZATION_VERSION) {
            LOGGER.warn("Deserialized version [%d] is different than serialization version [%d",
                    serializationVersion, ENCRYPTED_MULTIPART_UPLOAD_SERIALIZATION_VERSION);
        }

        upload = (EncryptedMultipartUpload<WRAPPED>) kryo.readClassAndObject(input);
    }

    return upload;
}

From source file:com.joyent.manta.serialization.EncryptedMultipartUploaSerializationHelper.java

License:Open Source License

/**
 * Extracts the cipher text value from a byte array.
 *
 * @param serializedData byte array to extract ciphertext from
 * @param ivLength size of IV//  www .j  a v a 2  s  .co m
 * @param hmacLength size of HMAC (or null for AEAD ciphers)
 * @return byte array containing only ciphertext
 */
private byte[] extractCipherText(final byte[] serializedData, final int ivLength, final Integer hmacLength) {
    if (hmacLength == null) {
        return Arrays.copyOfRange(serializedData, ivLength, serializedData.length);
    } else {
        return Arrays.copyOfRange(serializedData, ivLength,
                serializedData.length - hmacLength - CIPHER_ID_SIZE_BYTES);
    }
}

From source file:de.rub.nds.tlsattacker.dtls.workflow.Dtls12WorkflowExecutor.java

License:Apache License

private void sendDataBuffered(byte[] records, int currentMessagePointer) throws IOException {
    recordSendBuffer = ArrayConverter.concatenate(recordSendBuffer, records);
    if (handlingMyLastProtocolMessage(protocolMessages, currentMessagePointer)) {
        LOGGER.debug("Sending the following protocol messages to DTLS peer: {}",
                ArrayConverter.bytesToHexString(recordSendBuffer));
        int pointer = 0;
        int currentRecordSize = 0;
        byte[] sendBuffer = new byte[0];

        while (pointer < recordSendBuffer.length) {
            currentRecordSize = (recordSendBuffer[pointer + 11] << 8) + (recordSendBuffer[pointer + 12] & 0xFF)
                    + 13;/*from ww w.  j a  va 2  s.  com*/
            if ((sendBuffer.length + currentRecordSize) > maxPacketSize) {
                transportHandler.sendData(sendBuffer);
                sendBuffer = new byte[0];
            } else {
                sendBuffer = ArrayConverter.concatenate(sendBuffer,
                        Arrays.copyOfRange(recordSendBuffer, pointer, pointer + currentRecordSize));
                recordSendBuffer = Arrays.copyOfRange(recordSendBuffer, pointer + currentRecordSize,
                        recordSendBuffer.length);
            }
        }
        if (sendBuffer.length > 0) {
            transportHandler.sendData(sendBuffer);
        }
        recordSendBuffer = new byte[0];
    }
}

From source file:de.rub.nds.tlsattacker.tls.protocol.handshake.ECDHClientKeyExchangeHandler.java

License:Apache License

@Override
byte[] prepareKeyExchangeMessage() {
    if (tlsContext.getEcContext().getServerPublicKeyParameters() == null) {
        // we are probably handling a simple ECDH ciphersuite, we try to
        // establish server public key parameters from the server
        // certificate message
        Certificate x509Cert = tlsContext.getServerCertificate();

        SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo();
        ECPublicKeyParameters parameters;
        try {/*  w  w  w .j  a v  a  2  s  .c  o  m*/
            parameters = (ECPublicKeyParameters) PublicKeyFactory.createKey(keyInfo);
            ECPublicKeyParameters publicKeyParameters = (ECPublicKeyParameters) parameters;
            tlsContext.getEcContext().setServerPublicKeyParameters(parameters);
            LOGGER.debug("Parsed the following EC domain parameters from the certificate: ");
            LOGGER.debug("  Curve order: {}", publicKeyParameters.getParameters().getCurve().getOrder());
            LOGGER.debug("  Parameter A: {}", publicKeyParameters.getParameters().getCurve().getA());
            LOGGER.debug("  Parameter B: {}", publicKeyParameters.getParameters().getCurve().getB());
            LOGGER.debug("  Base point: {} ", publicKeyParameters.getParameters().getG());
            LOGGER.debug("  Public key point Q: {} ", publicKeyParameters.getQ());
        } catch (NoSuchMethodError e) {
            LOGGER.debug("The method was not found. It is possible that it is because an older bouncy castle"
                    + " library was used. We try to proceed the workflow.", e);
        } catch (IOException e) {
            throw new WorkflowExecutionException("Problem in parsing public key parameters from certificate",
                    e);
        }
    }

    AsymmetricCipherKeyPair kp = TlsECCUtils.generateECKeyPair(new SecureRandom(),
            tlsContext.getEcContext().getServerPublicKeyParameters().getParameters());

    ECPublicKeyParameters ecPublicKey = (ECPublicKeyParameters) kp.getPublic();
    ECPrivateKeyParameters ecPrivateKey = (ECPrivateKeyParameters) kp.getPrivate();

    // do some ec point modification
    protocolMessage.setPublicKeyBaseX(ecPublicKey.getQ().getAffineXCoord().toBigInteger());
    protocolMessage.setPublicKeyBaseY(ecPublicKey.getQ().getAffineYCoord().toBigInteger());

    ECCurve curve = ecPublicKey.getParameters().getCurve();
    ECPoint point = curve.createPoint(protocolMessage.getPublicKeyBaseX().getValue(),
            protocolMessage.getPublicKeyBaseY().getValue());

    LOGGER.debug("Using the following point:");
    LOGGER.debug("X: " + protocolMessage.getPublicKeyBaseX().getValue().toString());
    LOGGER.debug("Y: " + protocolMessage.getPublicKeyBaseY().getValue().toString());

    // System.out.println("-----------------\nUsing the following point:");
    // System.out.println("X: " + point.getAffineXCoord());
    // System.out.println("Y: " + point.getAffineYCoord());
    // System.out.println("-----------------\n");
    ECPointFormat[] pointFormats = tlsContext.getEcContext().getServerPointFormats();

    try {
        byte[] serializedPoint = ECCUtilsBCWrapper.serializeECPoint(pointFormats, point);
        protocolMessage.setEcPointFormat(serializedPoint[0]);
        protocolMessage.setEcPointEncoded(Arrays.copyOfRange(serializedPoint, 1, serializedPoint.length));
        protocolMessage.setPublicKeyLength(serializedPoint.length);

        byte[] result = ArrayConverter.concatenate(
                new byte[] { protocolMessage.getPublicKeyLength().getValue().byteValue() },
                new byte[] { protocolMessage.getEcPointFormat().getValue() },
                protocolMessage.getEcPointEncoded().getValue());

        byte[] premasterSecret = TlsECCUtils.calculateECDHBasicAgreement(
                tlsContext.getEcContext().getServerPublicKeyParameters(), ecPrivateKey);
        byte[] random = tlsContext.getClientServerRandom();
        protocolMessage.setPremasterSecret(premasterSecret);
        LOGGER.debug("Computed PreMaster Secret: {}",
                ArrayConverter.bytesToHexString(protocolMessage.getPremasterSecret().getValue()));
        LOGGER.debug("Client Server Random: {}", ArrayConverter.bytesToHexString(random));

        PRFAlgorithm prfAlgorithm = AlgorithmResolver.getPRFAlgorithm(tlsContext.getProtocolVersion(),
                tlsContext.getSelectedCipherSuite());
        byte[] masterSecret = PseudoRandomFunction.compute(prfAlgorithm,
                protocolMessage.getPremasterSecret().getValue(), PseudoRandomFunction.MASTER_SECRET_LABEL,
                random, HandshakeByteLength.MASTER_SECRET);
        LOGGER.debug("Computed Master Secret: {}", ArrayConverter.bytesToHexString(masterSecret));

        protocolMessage.setMasterSecret(masterSecret);
        tlsContext.setMasterSecret(protocolMessage.getMasterSecret().getValue());

        return result;

    } catch (IOException ex) {
        throw new WorkflowExecutionException("EC point serialization failure", ex);
    }
}

From source file:dorkbox.network.connection.registration.remote.RegistrationRemoteHandlerServer.java

License:Apache License

@SuppressWarnings("Duplicates")
void readServer(final ChannelHandlerContext context, final Channel channel, final Registration registration,
        final String type, final MetaChannel metaChannel) {
    final InetSocketAddress remoteAddress = (InetSocketAddress) channel.remoteAddress();

    //  IN: session ID == 0 (start of new connection)
    // OUT: session ID + public key + ecc parameters (which are a nonce. the SERVER defines what these are)
    if (registration.sessionID == 0) {
        // whoa! Didn't send valid public key info!
        if (invalidPublicKey(registration, type)) {
            shutdown(channel, registration.sessionID);
            return;
        }/*from  ww w  .jav  a  2  s  . c o m*/

        // want to validate the public key used! This is similar to how SSH works, in that once we use a public key, we want to validate
        // against that ip-address::key pair, so we can better protect against MITM/spoof attacks.
        if (invalidRemoteAddress(metaChannel, registration, type, remoteAddress)) {
            // whoa! abort since something messed up! (log and recording if key changed happens inside of validate method)
            shutdown(channel, registration.sessionID);
            return;
        }

        // save off remote public key. This is ALWAYS the same, where the ECDH changes every time...
        metaChannel.publicKey = registration.publicKey;

        // tell the client to continue it's registration process.
        Registration outboundRegister = new Registration(metaChannel.sessionId);
        outboundRegister.publicKey = registrationWrapper.getPublicKey();
        outboundRegister.eccParameters = CryptoECC
                .generateSharedParameters(registrationWrapper.getSecureRandom());

        channel.writeAndFlush(outboundRegister);
        return;
    }

    //  IN: remote ECDH shared payload
    // OUT: server ECDH shared payload
    if (metaChannel.aesKey == null) {
        /*
         * Diffie-Hellman-Merkle key exchange for the AES key
         * http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange
         */

        // the ECDH key will ROTATE every 10 minutes, since generating it for EVERY connection is expensive
        // and since we are combining ECDHE+ECC public/private keys for each connection, other
        // connections cannot break someone else's connection, since they are still protected by their own private keys.
        metaChannel.ecdhKey = getEchdKeyOnRotate(registrationWrapper.getSecureRandom());

        byte[] ecdhPubKeyBytes = java.util.Arrays.copyOfRange(registration.payload, 0,
                registration.payload.length);
        ECPublicKeyParameters ecdhPubKey;
        try {
            ecdhPubKey = EccPublicKeySerializer.read(new Input(ecdhPubKeyBytes));
        } catch (KryoException e) {
            logger.error("Invalid decode of ECDH public key. Aborting.");
            shutdown(channel, registration.sessionID);
            return;
        }

        BasicAgreement agreement = new ECDHCBasicAgreement();
        agreement.init(metaChannel.ecdhKey.getPrivate());
        BigInteger shared = agreement.calculateAgreement(ecdhPubKey);

        // now we setup our AES key based on our shared secret! (from ECDH)
        // the shared secret is different each time a connection is made
        byte[] keySeed = shared.toByteArray();

        SHA384Digest sha384 = new SHA384Digest();
        byte[] digest = new byte[sha384.getDigestSize()];
        sha384.update(keySeed, 0, keySeed.length);
        sha384.doFinal(digest, 0);

        metaChannel.aesKey = Arrays.copyOfRange(digest, 0, 32); // 256bit keysize (32 bytes)
        metaChannel.aesIV = Arrays.copyOfRange(digest, 32, 44); // 96bit blocksize (12 bytes) required by AES-GCM

        if (invalidAES(metaChannel)) {
            // abort if something messed up!
            shutdown(channel, registration.sessionID);
            return;
        }

        Registration outboundRegister = new Registration(metaChannel.sessionId);

        Output output = new Output(1024);
        EccPublicKeySerializer.write(output, (ECPublicKeyParameters) metaChannel.ecdhKey.getPublic());
        outboundRegister.payload = output.toBytes();

        channel.writeAndFlush(outboundRegister);
        return;
    }

    // NOTE: if we have more registrations, we will "bounce back" that status so the client knows what to do.
    // IN: hasMore=true if we have more registrations to do, false otherwise

    // ALWAYS upgrade the connection at this point.
    // IN: upgraded=false if we haven't upgraded to encryption yet (this will always be the case right after encryption is setup)

    if (!registration.upgraded) {
        // upgrade the connection to an encrypted connection
        registration.upgrade = true;
        upgradeDecoders(channel, metaChannel);

        // bounce back to the client so it knows we received it
        channel.write(registration);

        // this pipeline encoder/decoder can now be upgraded, and the "connection" added
        upgradeEncoders(channel, metaChannel, remoteAddress);

        if (!registration.hasMore) {
            // we only get this when we are 100% done with the registration of all connection types.

            // setup the pipeline with the real connection
            upgradePipeline(metaChannel, remoteAddress);
        }

        channel.flush();
        return;
    }

    // the client will send their class registration data. VERIFY IT IS CORRECT!
    STATE state = registrationWrapper.verifyClassRegistration(metaChannel, registration);
    if (state == STATE.ERROR) {
        // abort! There was an error
        shutdown(channel, registration.sessionID);
        return;
    } else if (state == STATE.WAIT) {
        return;
    }
    // else, continue.

    //
    //
    // we only get this when we are 100% done with the registration of all connection types.
    //      the context is the LAST protocol to be registered
    //
    //

    // remove the ConnectionWrapper (that was used to upgrade the connection) and cleanup the pipeline
    cleanupPipeline(metaChannel, new Runnable() {
        @Override
        public void run() {
            // this method runs after the "onConnect()" runs and only after all of the channels have be correctly updated

            // this tells the client we are ready to connect (we just bounce back the original message over ALL protocols)
            if (metaChannel.tcpChannel != null) {
                logger.trace("Sending TCP upgraded command");
                Registration reg = new Registration(registration.sessionID);
                reg.upgraded = true;
                metaChannel.tcpChannel.writeAndFlush(reg);
            }

            if (metaChannel.udpChannel != null) {
                logger.trace("Sending UDP upgraded command");
                Registration reg = new Registration(registration.sessionID);
                reg.upgraded = true;
                metaChannel.udpChannel.writeAndFlush(reg);
            }
        }
    });
}

From source file:ee.ria.xroad.proxy.testsuite.testcases.Utf8BomAttachment2.java

License:Open Source License

@Override
protected void validateNormalResponse(Message receivedResponse) throws Exception {
    RequestHash requestHashFromResponse = ((SoapMessageImpl) receivedResponse.getSoap()).getHeader()
            .getRequestHash();/* ww  w .ja v a  2  s  . c om*/

    byte[] requestFileBytes = IOUtils.toByteArray(getRequestInput(false).getRight());
    byte[] requestSoapBytes = Arrays.copyOfRange(requestFileBytes, 64,
            1156 + getQueryId().getBytes("UTF-8").length);

    byte[] requestHash = CryptoUtils.calculateDigest(
            CryptoUtils.getAlgorithmId(requestHashFromResponse.getAlgorithmId()), requestSoapBytes);

    if (!Arrays.areEqual(requestHash, CryptoUtils.decodeBase64(requestHashFromResponse.getHash()))) {
        throw new RuntimeException("Request message hash does not match request message");
    }
}

From source file:jcifs.tests.ReadWriteTest.java

License:Open Source License

static void verifyRandom(int bufSize, long length, boolean expectEof, InputStream is) throws IOException {
    long start = System.currentTimeMillis();
    byte buffer[] = new byte[bufSize];
    long p = 0;/*from   ww w  . ja v a2 s  .c  o  m*/
    Random r = getRandom();
    while (p < length) {

        int rs = Math.min(bufSize, (int) (length - p));
        int read = is.read(buffer, 0, rs);
        if (read < 0) {
            fail("Unexpected EOF");
        }

        byte verify[] = new byte[read];
        randBytes(r, verify);
        byte actual[] = Arrays.copyOfRange(buffer, 0, read);

        assertArrayEquals("Data matches at offset " + p, actual, verify);

        p += read;
    }
    if (expectEof) {
        assertEquals("Expecting EOF", -1, is.read(buffer, 0, 1));
    }
    log.debug("Read " + length + " took " + (System.currentTimeMillis() - start));
}

From source file:org.ethereum.crypto.EthereumIESEngine.java

License:Open Source License

private byte[] decryptBlock(byte[] inEnc, int inOff, int inLen, byte[] macData)
        throws InvalidCipherTextException {
    byte[] m = null;
    byte[] k = null;
    byte[] k1 = null;
    byte[] k2 = null;

    int len;//w w  w.  j av  a 2s  .c  om

    // Ensure that the length of the input is greater than the MAC in bytes
    if (inLen <= (param.getMacKeySize() / 8)) {
        throw new InvalidCipherTextException("Length of input must be greater than the MAC");
    }

    if (cipher == null) {
        // Streaming mode.
        k1 = new byte[inLen - v.length - mac.getMacSize()];
        k2 = new byte[param.getMacKeySize() / 8];
        k = new byte[k1.length + k2.length];

        kdf.generateBytes(k, 0, k.length);

        //            if (v.length != 0)
        //            {
        //                System.arraycopy(K, 0, K2, 0, K2.length);
        //                System.arraycopy(K, K2.length, K1, 0, K1.length);
        //            }
        //            else
        {
            System.arraycopy(k, 0, k1, 0, k1.length);
            System.arraycopy(k, k1.length, k2, 0, k2.length);
        }

        m = new byte[k1.length];

        for (int i = 0; i != k1.length; i++) {
            m[i] = (byte) (inEnc[inOff + v.length + i] ^ k1[i]);
        }

        len = k1.length;
    } else {
        // Block cipher mode.
        k1 = new byte[((IESWithCipherParameters) param).getCipherKeySize() / 8];
        k2 = new byte[param.getMacKeySize() / 8];
        k = new byte[k1.length + k2.length];

        kdf.generateBytes(k, 0, k.length);
        System.arraycopy(k, 0, k1, 0, k1.length);
        System.arraycopy(k, k1.length, k2, 0, k2.length);

        // If iv provide use it to initialize the cipher
        if (iv != null) {
            cipher.init(false, new ParametersWithIV(new KeyParameter(k1), iv));
        } else {
            cipher.init(false, new KeyParameter(k1));
        }

        m = new byte[cipher.getOutputSize(inLen - v.length - mac.getMacSize())];
        len = cipher.processBytes(inEnc, inOff + v.length, inLen - v.length - mac.getMacSize(), m, 0);
        len += cipher.doFinal(m, len);
    }

    // Convert the length of the encoding vector into a byte array.
    byte[] p2 = param.getEncodingV();

    // Verify the MAC.
    int end = inOff + inLen;
    byte[] t1 = Arrays.copyOfRange(inEnc, end - mac.getMacSize(), end);

    byte[] t2 = new byte[t1.length];
    byte[] k2A;
    if (hashK2) {
        k2A = new byte[hash.getDigestSize()];
        hash.reset();
        hash.update(k2, 0, k2.length);
        hash.doFinal(k2A, 0);
    } else {
        k2A = k2;
    }
    mac.init(new KeyParameter(k2A));
    mac.update(iv, 0, iv.length);
    mac.update(inEnc, inOff + v.length, inLen - v.length - t2.length);

    if (p2 != null) {
        mac.update(p2, 0, p2.length);
    }

    if (v.length != 0 && p2 != null) {
        byte[] l2 = new byte[4];
        Pack.intToBigEndian(p2.length * 8, l2, 0);
        mac.update(l2, 0, l2.length);
    }

    if (macData != null) {
        mac.update(macData, 0, macData.length);
    }

    mac.doFinal(t2, 0);

    if (!Arrays.constantTimeAreEqual(t1, t2)) {
        throw new InvalidCipherTextException("Invalid MAC.");
    }

    // Output the message.
    return Arrays.copyOfRange(m, 0, len);
}

From source file:org.ethereum.crypto.EthereumIESEngine.java

License:Open Source License

public byte[] processBlock(byte[] in, int inOff, int inLen, byte[] macData) throws InvalidCipherTextException {
    if (forEncryption) {
        if (keyPairGenerator != null) {
            EphemeralKeyPair ephKeyPair = keyPairGenerator.generate();

            this.privParam = ephKeyPair.getKeyPair().getPrivate();
            this.v = ephKeyPair.getEncodedPublicKey();
        }/*from   w w w  . ja v  a2s .com*/
    } else {
        if (keyParser != null) {
            ByteArrayInputStream bIn = new ByteArrayInputStream(in, inOff, inLen);

            try {
                this.pubParam = keyParser.readKey(bIn);
            } catch (IOException e) {
                throw new InvalidCipherTextException(
                        "unable to recover ephemeral public key: " + e.getMessage(), e);
            }

            int encLength = (inLen - bIn.available());
            this.v = Arrays.copyOfRange(in, inOff, inOff + encLength);
        }
    }

    // Compute the common value and convert to byte array.
    agree.init(privParam);
    BigInteger z = agree.calculateAgreement(pubParam);
    byte[] Z = BigIntegers.asUnsignedByteArray(agree.getFieldSize(), z);

    // Create input to KDF.
    byte[] vz;
    //        if (v.length != 0)
    //        {
    //            VZ = new byte[v.length + Z.length];
    //            System.arraycopy(v, 0, VZ, 0, v.length);
    //            System.arraycopy(Z, 0, VZ, v.length, Z.length);
    //        }
    //        else
    {
        vz = Z;
    }

    // Initialise the KDF.
    DerivationParameters kdfParam;
    if (kdf instanceof MGF1BytesGeneratorExt) {
        kdfParam = new MGFParameters(vz);
    } else {
        kdfParam = new KDFParameters(vz, param.getDerivationV());
    }
    kdf.init(kdfParam);

    return forEncryption ? encryptBlock(in, inOff, inLen, macData) : decryptBlock(in, inOff, inLen, macData);
}