/** * @param keyLength Block size of the asymmetric cipher, in bits. I thought I can get it from * {@code asym.getBlockSize()} but that doesn't work with Sun's implementation. */ public CombinedCipherInputStream(InputStream in, Cipher asym, String algorithm, int keyLength) throws IOException, GeneralSecurityException { super(in); String keyAlgorithm = getKeyAlgorithm(algorithm); // first read the symmetric key cipher byte[] symKeyBytes = new byte[keyLength / 8]; new DataInputStream(in).readFully(symKeyBytes); SecretKey symKey = new SecretKeySpec(asym.doFinal(symKeyBytes), keyAlgorithm); // the rest of the data will be decrypted by this symmetric cipher Cipher sym = Secret.getCipher(algorithm); sym.init( Cipher.DECRYPT_MODE, symKey, keyAlgorithm.equals(algorithm) ? null : new IvParameterSpec(symKey.getEncoded())); super.in = new CipherInputStream(in, sym); }
public CombinedCipherOutputStream(OutputStream out, Cipher asym, String algorithm) throws IOException, GeneralSecurityException { super(out); // create a new symmetric cipher key used for this stream String keyAlgorithm = getKeyAlgorithm(algorithm); SecretKey symKey = KeyGenerator.getInstance(keyAlgorithm).generateKey(); // place the symmetric key by encrypting it with asymmetric cipher out.write(asym.doFinal(symKey.getEncoded())); // the rest of the data will be encrypted by this symmetric cipher Cipher sym = Secret.getCipher(algorithm); sym.init( Cipher.ENCRYPT_MODE, symKey, keyAlgorithm.equals(algorithm) ? null : new IvParameterSpec(symKey.getEncoded())); super.out = new CipherOutputStream(out, sym); }