/** * Encrypts the content passed-in. * * @param key the key used for the underlying cypher. * @param content the content to encrypted * @return {@code String} the encoded content as base64 encoded string. * @throws Exception */ public static String encrypt(final String key, final String content) throws Exception { final Cipher cipher = Cipher.getInstance(TRANSOFRMATION); final IvParameterSpec iv = getIV(); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec(key), iv); final byte[] encrypted = cipher.doFinal(content.getBytes(ASCII)); final String base64 = Base64.encodeBase64URLSafeString(prependIV(encrypted, iv.getIV())); return URLEncoder.encode(base64, ASCII.displayName()); }
// see JCE spec protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { byte[] ivValue; if (params != null) { if (params instanceof IvParameterSpec == false) { throw new InvalidAlgorithmParameterException("Only IvParameterSpec supported"); } IvParameterSpec ivSpec = (IvParameterSpec) params; ivValue = ivSpec.getIV(); } else { ivValue = null; } implInit(opmode, key, ivValue, random); }
// see JCE spec protected void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { byte[] ivValue; if (params != null) { try { IvParameterSpec ivSpec = (IvParameterSpec) params.getParameterSpec(IvParameterSpec.class); ivValue = ivSpec.getIV(); } catch (InvalidParameterSpecException e) { throw new InvalidAlgorithmParameterException("Could not decode IV", e); } } else { ivValue = null; } implInit(opmode, key, ivValue, random); }
public byte[] encode() { byte iv[] = ivParameter == null ? new byte[0] : ivParameter.getIV(); byte[] tab = new byte[4]; Bits.putInt(tab, 0, type.ordinal()); return Bits.concateEncodingWithShortSizedTabs( tab, Bits.concateEncodingWithShortSizedTabs( iv, SymmetricEncryptionType.encodeSecretKey(secretKey))); }
protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { CipherParameters param; if (key instanceof BCPBEKey) { BCPBEKey k = (BCPBEKey) key; if (params instanceof PBEParameterSpec) { param = PBE.Util.makePBEParameters(k, params, wrapEngine.getAlgorithmName()); } else if (k.getParam() != null) { param = k.getParam(); } else { throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set."); } } else { param = new KeyParameter(key.getEncoded()); } if (params instanceof IvParameterSpec) { IvParameterSpec iv = (IvParameterSpec) params; param = new ParametersWithIV(param, iv.getIV()); } if (param instanceof KeyParameter && ivSize != 0) { iv = new byte[ivSize]; random.nextBytes(iv); param = new ParametersWithIV(param, iv); } switch (opmode) { case Cipher.WRAP_MODE: wrapEngine.init(true, param); break; case Cipher.UNWRAP_MODE: wrapEngine.init(false, param); break; case Cipher.ENCRYPT_MODE: case Cipher.DECRYPT_MODE: throw new IllegalArgumentException("engine only valid for wrapping"); default: System.out.println("eeek!"); } }
private String decrypt(String cipherText, String key, int nBits) throws Exception { if (!(nBits == 128 || nBits == 192 || nBits == 256)) { return "Error: Must be a key mode of either 128, 192, 256 bits"; } if (cipherText == null || key == null) { return "Error: cipher and/or key equals null"; } byte[] decrypted; nBits = nBits / 8; byte[] data = Base64.decode(cipherText.toCharArray()); /* * CHECK: we should always use getBytes("UTF-8") or with wanted charset, never system charset! */ byte[] k = Arrays.copyOf(key.getBytes(), nBits); /* AES/CTR/NoPadding (SIC == CTR) */ org.bouncycastle.crypto.BufferedBlockCipher cipher = new org.bouncycastle.crypto.BufferedBlockCipher( new org.bouncycastle.crypto.modes.SICBlockCipher( new org.bouncycastle.crypto.engines.AESEngine())); cipher.reset(); SecretKey secretKey = generateSecretKey(k, nBits); byte[] nonceBytes = Arrays.copyOf(Arrays.copyOf(data, 8), nBits / 2); IvParameterSpec nonce = new IvParameterSpec(nonceBytes); /* true == encrypt; false == decrypt */ cipher.init( true, new org.bouncycastle.crypto.params.ParametersWithIV( new org.bouncycastle.crypto.params.KeyParameter(secretKey.getEncoded()), nonce.getIV())); decrypted = new byte[cipher.getOutputSize(data.length - 8)]; int decLength = cipher.processBytes(data, 8, data.length - 8, decrypted, 0); cipher.doFinal(decrypted, decLength); /* * CHECK: we should always use new String (bytes,charset) to avoid issues with system charset and utf-8 */ return new String(decrypted); }
@Override public boolean equals(Object o) { if (o == null) return false; if (o == this) return true; if (o instanceof SymmetricSecretKey) { SymmetricSecretKey other = ((SymmetricSecretKey) o); return secretKey.equals(other.secretKey) && type == other.type && ((ivParameter == null && other.ivParameter == null) || (ivParameter != null && other.ivParameter != null && Arrays.equals(ivParameter.getIV(), other.ivParameter.getIV()))); } return false; }
private static IvParameterSpec calculateIVForOffset( final IvParameterSpec iv, final long blockOffset) { final BigInteger ivBI = new BigInteger(1, iv.getIV()); final BigInteger ivForOffsetBI = ivBI.add(BigInteger.valueOf(blockOffset / BLOCK_SIZE)); final byte[] ivForOffsetBA = ivForOffsetBI.toByteArray(); final IvParameterSpec ivForOffset; if (ivForOffsetBA.length >= BLOCK_SIZE) { ivForOffset = new IvParameterSpec(ivForOffsetBA, ivForOffsetBA.length - BLOCK_SIZE, BLOCK_SIZE); } else { final byte[] ivForOffsetBASized = new byte[BLOCK_SIZE]; System.arraycopy( ivForOffsetBA, 0, ivForOffsetBASized, BLOCK_SIZE - ivForOffsetBA.length, ivForOffsetBA.length); ivForOffset = new IvParameterSpec(ivForOffsetBASized); } return ivForOffset; }
/** * Takes correctly padded data and encrypts it * * @param data correctly padded data * @return * @throws CryptoException */ public byte[] encrypt(byte[] data) throws CryptoException { try { byte[] ciphertext; if (useExplicitIv) { ciphertext = ArrayConverter.concatenate(encryptIv.getIV(), encryptCipher.doFinal(data)); } else { encryptCipher.init(Cipher.ENCRYPT_MODE, encryptKey, encryptIv); ciphertext = encryptCipher.doFinal(data); encryptIv = new IvParameterSpec( Arrays.copyOfRange( ciphertext, ciphertext.length - decryptCipher.getBlockSize(), ciphertext.length)); } return ciphertext; } catch (BadPaddingException | IllegalBlockSizeException | InvalidAlgorithmParameterException | InvalidKeyException ex) { throw new CryptoException(ex); } }
/** * Creates the instance of TLS v1 Connection State. All of the security parameters are provided by * session object. * * @param session: the sessin object which incapsulates all of the security parameters established * by handshake protocol. The key calculation for the state is done according to the TLS v 1.0 * Protocol specification. (http://www.ietf.org/rfc/rfc2246.txt) */ protected ConnectionStateTLS(SSLSessionImpl session) { try { CipherSuite cipherSuite = session.cipherSuite; hash_size = cipherSuite.getMACLength(); boolean is_exportabe = cipherSuite.isExportable(); int key_size = (is_exportabe) ? cipherSuite.keyMaterial : cipherSuite.expandedKeyMaterial; int iv_size = cipherSuite.getBlockSize(); String algName = cipherSuite.getBulkEncryptionAlgorithm(); String macName = cipherSuite.getHmacName(); if (logger != null) { logger.println("ConnectionStateTLS.create:"); logger.println(" cipher suite name: " + cipherSuite.getName()); logger.println(" encryption alg name: " + algName); logger.println(" mac alg name: " + macName); logger.println(" hash size: " + hash_size); logger.println(" block size: " + iv_size); logger.println(" IV size (== block size):" + iv_size); logger.println(" key size: " + key_size); } byte[] clientRandom = session.clientRandom; byte[] serverRandom = session.serverRandom; // so we need PRF value of size of // 2*hash_size + 2*key_size + 2*iv_size byte[] key_block = new byte[2 * hash_size + 2 * key_size + 2 * iv_size]; byte[] seed = new byte[clientRandom.length + serverRandom.length]; System.arraycopy(serverRandom, 0, seed, 0, serverRandom.length); System.arraycopy(clientRandom, 0, seed, serverRandom.length, clientRandom.length); PRF.computePRF(key_block, session.master_secret, KEY_EXPANSION_LABEL, seed); byte[] client_mac_secret = new byte[hash_size]; byte[] server_mac_secret = new byte[hash_size]; byte[] client_key = new byte[key_size]; byte[] server_key = new byte[key_size]; boolean is_client = !session.isServer; is_block_cipher = (iv_size > 0); // do not count, as block_size is always 8 // block_size = iv_size; System.arraycopy(key_block, 0, client_mac_secret, 0, hash_size); System.arraycopy(key_block, hash_size, server_mac_secret, 0, hash_size); System.arraycopy(key_block, 2 * hash_size, client_key, 0, key_size); System.arraycopy(key_block, 2 * hash_size + key_size, server_key, 0, key_size); IvParameterSpec clientIV = null; IvParameterSpec serverIV = null; if (is_exportabe) { System.arraycopy(clientRandom, 0, seed, 0, clientRandom.length); System.arraycopy(serverRandom, 0, seed, clientRandom.length, serverRandom.length); byte[] final_client_key = new byte[cipherSuite.expandedKeyMaterial]; byte[] final_server_key = new byte[cipherSuite.expandedKeyMaterial]; PRF.computePRF(final_client_key, client_key, CLIENT_WRITE_KEY_LABEL, seed); PRF.computePRF(final_server_key, server_key, SERVER_WRITE_KEY_LABEL, seed); client_key = final_client_key; server_key = final_server_key; if (is_block_cipher) { byte[] iv_block = new byte[2 * iv_size]; PRF.computePRF(iv_block, null, IV_BLOCK_LABEL, seed); clientIV = new IvParameterSpec(iv_block, 0, iv_size); serverIV = new IvParameterSpec(iv_block, iv_size, iv_size); } } else if (is_block_cipher) { clientIV = new IvParameterSpec(key_block, 2 * (hash_size + key_size), iv_size); serverIV = new IvParameterSpec(key_block, 2 * (hash_size + key_size) + iv_size, iv_size); } if (logger != null) { logger.println("is exportable: " + is_exportabe); logger.println("master_secret"); logger.print(session.master_secret); logger.println("client_random"); logger.print(clientRandom); logger.println("server_random"); logger.print(serverRandom); // logger.println("key_block"); // logger.print(key_block); logger.println("client_mac_secret"); logger.print(client_mac_secret); logger.println("server_mac_secret"); logger.print(server_mac_secret); logger.println("client_key"); logger.print(client_key); logger.println("server_key"); logger.print(server_key); if (clientIV == null) { logger.println("no IV."); } else { logger.println("client_iv"); logger.print(clientIV.getIV()); logger.println("server_iv"); logger.print(serverIV.getIV()); } } encCipher = Cipher.getInstance(algName); decCipher = Cipher.getInstance(algName); encMac = Mac.getInstance(macName); decMac = Mac.getInstance(macName); if (is_client) { // client side encCipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(client_key, algName), clientIV); decCipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(server_key, algName), serverIV); encMac.init(new SecretKeySpec(client_mac_secret, macName)); decMac.init(new SecretKeySpec(server_mac_secret, macName)); } else { // server side encCipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(server_key, algName), serverIV); decCipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(client_key, algName), clientIV); encMac.init(new SecretKeySpec(server_mac_secret, macName)); decMac.init(new SecretKeySpec(client_mac_secret, macName)); } } catch (Exception e) { e.printStackTrace(); throw new AlertException( AlertProtocol.INTERNAL_ERROR, new SSLProtocolException("Error during computation of security parameters")); } }
protected void saveToJarXML(HashMap detailsToJarXML) throws TransformerException, ParserConfigurationException { DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document document = documentBuilder.newDocument(); Element rootElement = document.createElement("JarConfig"); document.appendChild(rootElement); if (detailsToJarXML.get(FileSecConstants.JARXML_NOTBEFORE) != null) { Element notBeforeElement = document.createElement(FileSecConstants.JARXML_NOTBEFORE); String notBefore = (String) detailsToJarXML.get(FileSecConstants.JARXML_NOTBEFORE); notBeforeElement.appendChild(document.createTextNode(notBefore)); rootElement.appendChild(notBeforeElement); } if (detailsToJarXML.get(FileSecConstants.JARXML_NOTAFTER) != null) { Element notAfterElement = document.createElement(FileSecConstants.JARXML_NOTAFTER); String notAfter = (String) detailsToJarXML.get(FileSecConstants.JARXML_NOTAFTER); notAfterElement.appendChild(document.createTextNode(notAfter)); rootElement.appendChild(notAfterElement); } if (detailsToJarXML.get(FileSecConstants.JARXML_SYMMETRIC_CIPHER) != null) { Element symmetricCipherElement = document.createElement(FileSecConstants.JARXML_SYMMETRIC_CIPHER); String symmetricCipher = (String) detailsToJarXML.get(FileSecConstants.JARXML_SYMMETRIC_CIPHER); symmetricCipherElement.appendChild(document.createTextNode(symmetricCipher)); rootElement.appendChild(symmetricCipherElement); } if (detailsToJarXML.get(FileSecConstants.JARXML_SYMMETRIC_KEYTYPE) != null) { Element symmetricKeyTypeElement = document.createElement(FileSecConstants.JARXML_SYMMETRIC_KEYTYPE); String symmetricKeyType = (String) detailsToJarXML.get(FileSecConstants.JARXML_SYMMETRIC_KEYTYPE); symmetricKeyTypeElement.appendChild(document.createTextNode(symmetricKeyType)); rootElement.appendChild(symmetricKeyTypeElement); } if (detailsToJarXML.get(FileSecConstants.JARXML_SYMMETRIC_KEYSIZE) != null) { Element symmetricKeySizeElement = document.createElement(FileSecConstants.JARXML_SYMMETRIC_KEYSIZE); String symmetricKeySize = (String) detailsToJarXML.get(FileSecConstants.JARXML_SYMMETRIC_KEYSIZE); symmetricKeySizeElement.appendChild(document.createTextNode(symmetricKeySize)); rootElement.appendChild(symmetricKeySizeElement); } if (detailsToJarXML.get(FileSecConstants.JARXML_ASYMMETRIC_CIPHER) != null) { Element asymmetricCipherElement = document.createElement(FileSecConstants.JARXML_ASYMMETRIC_CIPHER); String asymmetricCipher = (String) detailsToJarXML.get(FileSecConstants.JARXML_ASYMMETRIC_CIPHER); asymmetricCipherElement.appendChild(document.createTextNode(asymmetricCipher)); rootElement.appendChild(asymmetricCipherElement); } if (detailsToJarXML.get(FileSecConstants.JARXML_ASYMMETRIC_SIGN) != null) { Element asymmetricCipherElement = document.createElement(FileSecConstants.JARXML_ASYMMETRIC_SIGN); String asymmetricCipher = (String) detailsToJarXML.get(FileSecConstants.JARXML_ASYMMETRIC_SIGN); asymmetricCipherElement.appendChild(document.createTextNode(asymmetricCipher)); rootElement.appendChild(asymmetricCipherElement); } if (detailsToJarXML.get(FileSecConstants.JARXML_PBE_KEYTYPE) != null) { Element pbeCiperKeyTypeElement = document.createElement(FileSecConstants.JARXML_PBE_KEYTYPE); String pbeCiperKeyType = (String) detailsToJarXML.get(FileSecConstants.JARXML_PBE_KEYTYPE); pbeCiperKeyTypeElement.appendChild(document.createTextNode(pbeCiperKeyType)); rootElement.appendChild(pbeCiperKeyTypeElement); } if (detailsToJarXML.get(FileSecConstants.JARXML_PBE_CIPHER) != null) { Element pbeCipherElement = document.createElement(FileSecConstants.JARXML_PBE_CIPHER); String pbeCipher = (String) detailsToJarXML.get(FileSecConstants.JARXML_PBE_CIPHER); pbeCipherElement.appendChild(document.createTextNode(pbeCipher)); rootElement.appendChild(pbeCipherElement); } if (detailsToJarXML.get(FileSecConstants.JARXML_MAC_HASHALGORITHM) != null) { Element MACHashAlgorithmElement = document.createElement(FileSecConstants.JARXML_MAC_HASHALGORITHM); String strMACHashAlgorithm = (String) detailsToJarXML.get(FileSecConstants.JARXML_MAC_HASHALGORITHM); MACHashAlgorithmElement.appendChild(document.createTextNode(strMACHashAlgorithm)); rootElement.appendChild(MACHashAlgorithmElement); } if (detailsToJarXML.get(FileSecConstants.JARXML_SIGNATURE) != null) { Element sigElement = document.createElement(FileSecConstants.JARXML_SIGNATURE); String signature = (String) detailsToJarXML.get(FileSecConstants.JARXML_SIGNATURE); sigElement.appendChild(document.createTextNode(signature)); rootElement.appendChild(sigElement); } if (detailsToJarXML.get(FileSecConstants.JARXML_SIGNING_ALIAS) != null) { Element aliasElement = document.createElement(FileSecConstants.JARXML_SIGNING_ALIAS); String alias = (String) detailsToJarXML.get(FileSecConstants.JARXML_SIGNING_ALIAS); aliasElement.appendChild(document.createTextNode(alias)); rootElement.appendChild(aliasElement); } if (detailsToJarXML.get(FileSecConstants.JARXML_ENCRYPTED_PKI_SESSIONKEY) != null) { Element sessionKeyElement = document.createElement(FileSecConstants.JARXML_ENCRYPTED_PKI_SESSIONKEY); String encSessionKey = (String) detailsToJarXML.get(FileSecConstants.JARXML_ENCRYPTED_PKI_SESSIONKEY); sessionKeyElement.appendChild(document.createTextNode(encSessionKey)); rootElement.appendChild(sessionKeyElement); } if (detailsToJarXML.get(FileSecConstants.JARXML_IVPARAM) != null) { Element ivParamElement = document.createElement(FileSecConstants.JARXML_IVPARAM); IvParameterSpec ivParam = (IvParameterSpec) detailsToJarXML.get(FileSecConstants.JARXML_IVPARAM); BASE64Encoder encoder = new BASE64Encoder(); String strIvParam = encoder.encode(ivParam.getIV()); ivParamElement.appendChild(document.createTextNode(strIvParam)); rootElement.appendChild(ivParamElement); } if (detailsToJarXML.get(FileSecConstants.JARXML_MAC) != null) { Element macElement = document.createElement(FileSecConstants.JARXML_MAC); String mac = (String) detailsToJarXML.get(FileSecConstants.JARXML_MAC); macElement.appendChild(document.createTextNode(mac)); rootElement.appendChild(macElement); } if (detailsToJarXML.get(FileSecConstants.JARXML_ENCRYPTED_SESSIONKEY_MAP) != null) { Element encryptedSessionKeyMapElement = document.createElement(FileSecConstants.JARXML_ENCRYPTED_PBE_SESSIONKEY); ArrayList encryptedSessionKeyMap = (ArrayList) detailsToJarXML.get(FileSecConstants.JARXML_ENCRYPTED_SESSIONKEY_MAP); ArrayList hashKeyMap = (ArrayList) detailsToJarXML.get(FileSecConstants.JARXML_HASHED_SESSIONKEY_MAP); for (int iKeyCount = 0; iKeyCount < encryptedSessionKeyMap.size(); iKeyCount++) { String encryptedKey = (String) encryptedSessionKeyMap.get(iKeyCount); String hashOfKey = (String) hashKeyMap.get(iKeyCount); Element keyElement = document.createElement(FileSecConstants.JARXML_KEY); keyElement.appendChild(document.createTextNode(encryptedKey)); Element hashElement = document.createElement(FileSecConstants.JARXML_HASH); hashElement.appendChild(document.createTextNode(hashOfKey)); encryptedSessionKeyMapElement.appendChild(keyElement); encryptedSessionKeyMapElement.appendChild(hashElement); } rootElement.appendChild(encryptedSessionKeyMapElement); } SimpleDateFormat formatter = new SimpleDateFormat(FileSecConstants.DATE_FORMAT); Date currentTimeStamp = new Date(); String strCurrentTimeStamp = formatter.format(currentTimeStamp); Element currentTimeElement = document.createElement(FileSecConstants.JARXML_CURRENT_TIMESTAMP); currentTimeElement.appendChild(document.createTextNode(strCurrentTimeStamp)); rootElement.appendChild(currentTimeElement); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource source = new DOMSource(document); StreamResult result = new StreamResult(new File(FileSecConstants.DEFAULT_JAR_CONFIG_FILE)); transformer.transform(source, result); }
/* * Calculate the keys needed for this connection, once the session's * master secret has been calculated. Uses the master key and nonces; * the amount of keying material generated is a function of the cipher * suite that's been negotiated. * * This gets called both on the "full handshake" (where we exchanged * a premaster secret and started a new session) as well as on the * "fast handshake" (where we just resumed a pre-existing session). */ void calculateConnectionKeys(SecretKey masterKey) { /* * For both the read and write sides of the protocol, we use the * master to generate MAC secrets and cipher keying material. Block * ciphers need initialization vectors, which we also generate. * * First we figure out how much keying material is needed. */ int hashSize = cipherSuite.macAlg.size; boolean is_exportable = cipherSuite.exportable; BulkCipher cipher = cipherSuite.cipher; int expandedKeySize = is_exportable ? cipher.expandedKeySize : 0; // Which algs/params do we need to use? String keyMaterialAlg; PRF prf; if (protocolVersion.v >= ProtocolVersion.TLS12.v) { keyMaterialAlg = "SunTls12KeyMaterial"; prf = cipherSuite.prfAlg; } else { keyMaterialAlg = "SunTlsKeyMaterial"; prf = P_NONE; } String prfHashAlg = prf.getPRFHashAlg(); int prfHashLength = prf.getPRFHashLength(); int prfBlockSize = prf.getPRFBlockSize(); TlsKeyMaterialParameterSpec spec = new TlsKeyMaterialParameterSpec( masterKey, protocolVersion.major, protocolVersion.minor, clnt_random.random_bytes, svr_random.random_bytes, cipher.algorithm, cipher.keySize, expandedKeySize, cipher.ivSize, hashSize, prfHashAlg, prfHashLength, prfBlockSize); try { KeyGenerator kg = JsseJce.getKeyGenerator(keyMaterialAlg); kg.init(spec); TlsKeyMaterialSpec keySpec = (TlsKeyMaterialSpec) kg.generateKey(); clntWriteKey = keySpec.getClientCipherKey(); svrWriteKey = keySpec.getServerCipherKey(); // Return null if IVs are not supposed to be generated. // e.g. TLS 1.1+. clntWriteIV = keySpec.getClientIv(); svrWriteIV = keySpec.getServerIv(); clntMacSecret = keySpec.getClientMacKey(); svrMacSecret = keySpec.getServerMacKey(); } catch (GeneralSecurityException e) { throw new ProviderException(e); } // // Dump the connection keys as they're generated. // if (debug != null && Debug.isOn("keygen")) { synchronized (System.out) { HexDumpEncoder dump = new HexDumpEncoder(); System.out.println("CONNECTION KEYGEN:"); // Inputs: System.out.println("Client Nonce:"); printHex(dump, clnt_random.random_bytes); System.out.println("Server Nonce:"); printHex(dump, svr_random.random_bytes); System.out.println("Master Secret:"); printHex(dump, masterKey.getEncoded()); // Outputs: System.out.println("Client MAC write Secret:"); printHex(dump, clntMacSecret.getEncoded()); System.out.println("Server MAC write Secret:"); printHex(dump, svrMacSecret.getEncoded()); if (clntWriteKey != null) { System.out.println("Client write key:"); printHex(dump, clntWriteKey.getEncoded()); System.out.println("Server write key:"); printHex(dump, svrWriteKey.getEncoded()); } else { System.out.println("... no encryption keys used"); } if (clntWriteIV != null) { System.out.println("Client write IV:"); printHex(dump, clntWriteIV.getIV()); System.out.println("Server write IV:"); printHex(dump, svrWriteIV.getIV()); } else { if (protocolVersion.v >= ProtocolVersion.TLS11.v) { System.out.println("... no IV derived for this protocol"); } else { System.out.println("... no IV used for this cipher"); } } System.out.flush(); } } }