in src/main/java/org/apache/xml/security/encryption/XMLCipher.java [1094:1206]
private EncryptedData encryptData(
Document context, Element element, String type, InputStream serializedData
) throws /* XMLEncryption */ Exception {
contextDocument = context;
if (algorithm == null) {
throw new XMLEncryptionException("empty", "XMLCipher instance without transformation specified");
}
if (element != null && element.getParentNode() == null) {
throw new XMLEncryptionException("empty", "The element can't be serialized as it has no parent");
}
byte[] serializedOctets = null;
if (serializedData == null) {
if (EncryptionConstants.TYPE_CONTENT.equals(type)) {
if (element == null) {
throw new XMLEncryptionException("empty", "Cannot encrypt null element");
}
NodeList children = element.getChildNodes();
if (null != children) {
serializedOctets = serializer.serializeToByteArray(children);
} else {
throw new XMLEncryptionException("empty", "Element has no content.");
}
} else {
serializedOctets = serializer.serializeToByteArray(element);
}
if (LOG.isLoggable(Level.DEBUG)) {
LOG.log(Level.DEBUG, "Serialized octets:\n" + new String(serializedOctets, StandardCharsets.UTF_8));
}
}
byte[] encryptedBytes = null;
// Now create the working cipher if none was created already
Cipher c;
if (contextCipher == null) {
c = constructCipher(algorithm, null);
} else {
c = contextCipher;
}
// Now perform the encryption
int ivLen = JCEMapper.getIVLengthFromURI(algorithm) / 8;
byte[] iv = XMLSecurityConstants.generateBytes(ivLen);
try {
AlgorithmParameterSpec paramSpec = constructBlockCipherParameters(algorithm, iv);
c.init(cipherMode, key, paramSpec);
} catch (InvalidKeyException ike) {
throw new XMLEncryptionException(ike);
}
try {
if (serializedData != null) {
int numBytes;
byte[] buf = new byte[8192];
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
while ((numBytes = serializedData.read(buf)) != -1) {
byte[] data = c.update(buf, 0, numBytes);
if (data != null) {
baos.write(data);
}
}
baos.write(c.doFinal());
encryptedBytes = baos.toByteArray();
}
} else {
encryptedBytes = c.doFinal(serializedOctets);
if (LOG.isLoggable(Level.DEBUG)) {
LOG.log(Level.DEBUG, "Expected cipher.outputSize = " +
Integer.toString(c.getOutputSize(serializedOctets.length)));
}
}
if (LOG.isLoggable(Level.DEBUG)) {
LOG.log(Level.DEBUG, "Actual cipher.outputSize = "
+ Integer.toString(encryptedBytes.length));
}
} catch (IllegalStateException | IllegalBlockSizeException
| BadPaddingException | UnsupportedEncodingException e) {
throw new XMLEncryptionException(e);
}
// Get IV from Cipher Object. If this is null (see BouncyCastle issue BJA-473) then use
// the original IV that was generated
if (c.getIV() != null) {
iv = c.getIV();
}
// Now build up to a properly XML Encryption encoded octet stream
byte[] finalEncryptedBytes = new byte[iv.length + encryptedBytes.length];
System.arraycopy(iv, 0, finalEncryptedBytes, 0, iv.length);
System.arraycopy(encryptedBytes, 0, finalEncryptedBytes, iv.length, encryptedBytes.length);
String base64EncodedEncryptedOctets = XMLUtils.encodeToString(finalEncryptedBytes);
LOG.log(Level.DEBUG, "Encrypted octets:\n{0}", base64EncodedEncryptedOctets);
LOG.log(Level.DEBUG, "Encrypted octets length = {0}", base64EncodedEncryptedOctets.length());
try {
CipherData cd = ed.getCipherData();
CipherValue cv = cd.getCipherValue();
cv.setValue(base64EncodedEncryptedOctets);
if (type != null) {
ed.setType(new URI(type).toString());
}
EncryptionMethod method =
factory.newEncryptionMethod(new URI(algorithm).toString());
method.setDigestAlgorithm(digestAlg);
ed.setEncryptionMethod(method);
} catch (URISyntaxException ex) {
throw new XMLEncryptionException(ex);
}
return ed;
}