XMLCipherpublic class XMLCipher extends Object XMLCipher encrypts and decrypts the contents of
Document s, Element s and Element
contents. It was designed to resemble javax.crypto.Cipher in
order to facilitate understanding of its functioning. |
Fields Summary |
---|
private static Logger | logger | public static final String | TRIPLEDESTriple DES EDE (192 bit key) in CBC mode | public static final String | AES_128AES 128 Cipher | public static final String | AES_256AES 256 Cipher | public static final String | AES_192AES 192 Cipher | public static final String | RSA_v1dot5RSA 1.5 Cipher | public static final String | RSA_OAEPRSA OAEP Cipher | public static final String | DIFFIE_HELLMANDIFFIE_HELLMAN Cipher | public static final String | TRIPLEDES_KeyWrapTriple DES EDE (192 bit key) in CBC mode KEYWRAP | public static final String | AES_128_KeyWrapAES 128 Cipher KeyWrap | public static final String | AES_256_KeyWrapAES 256 Cipher KeyWrap | public static final String | AES_192_KeyWrapAES 192 Cipher KeyWrap | public static final String | SHA1SHA1 Cipher | public static final String | SHA256SHA256 Cipher | public static final String | SHA512SHA512 Cipher | public static final String | RIPEMD_160RIPEMD Cipher | public static final String | XML_DSIGXML Signature NS | public static final String | N14C_XMLN14C_XML | public static final String | N14C_XML_WITH_COMMENTSN14C_XML with comments | public static final String | EXCL_XML_N14CN14C_XML excluisve | public static final String | EXCL_XML_N14C_WITH_COMMENTSN14C_XML exclusive with commetns | public static final String | BASE64_ENCODINGBase64 encoding | public static final int | ENCRYPT_MODEENCRYPT Mode | public static final int | DECRYPT_MODEDECRYPT Mode | public static final int | UNWRAP_MODEUNWRAP Mode | public static final int | WRAP_MODEWRAP Mode | private static final String | ENC_ALGORITHMS | private Cipher | _contextCipherCipher created during initialisation that is used for encryption | private int | _cipherModeMode that the XMLCipher object is operating in | private String | _algorithmURI of algorithm that is being used for cryptographic operation | private String | _requestedJCEProviderCryptographic provider requested by caller | private Canonicalizer | _canonHolds c14n to serialize, if initialized then _always_ use this c14n to serialize | private Document | _contextDocumentUsed for creation of DOM nodes in WRAP and ENCRYPT modes | private Factory | _factoryInstance of factory used to create XML Encryption objects | private Serializer | _serializerInternal serializer class for going to/from UTF-8 | private Key | _keyLocal copy of user's key | private Key | _kekLocal copy of the kek (used to decrypt EncryptedKeys during a
DECRYPT_MODE operation | private EncryptedKey | _ek | private EncryptedData | _ed |
Constructors Summary |
---|
private XMLCipher()Creates a new XMLCipher .
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Constructing XMLCipher...");
_factory = new Factory();
_serializer = new Serializer();
|
Methods Summary |
---|
public AgreementMethod | createAgreementMethod(java.lang.String algorithm)Create an AgreementMethod object
return (_factory.newAgreementMethod(algorithm));
| public CipherData | createCipherData(int type)Create a CipherData object
return (_factory.newCipherData(type));
| public CipherReference | createCipherReference(java.lang.String uri)Create a CipherReference object
return (_factory.newCipherReference(uri));
| public CipherValue | createCipherValue(java.lang.String value)Create a CipherValue element
return (_factory.newCipherValue(value));
| public EncryptedData | createEncryptedData(int type, java.lang.String value)Creates an EncryptedData Element .
The newEncryptedData and newEncryptedKey methods create fairly complete
elements that are immediately useable. All the other create* methods
return bare elements that still need to be built upon.
An EncryptionMethod will still need to be added however
EncryptedData result = null;
CipherData data = null;
switch (type) {
case CipherData.REFERENCE_TYPE:
CipherReference cipherReference = _factory.newCipherReference(
value);
data = _factory.newCipherData(type);
data.setCipherReference(cipherReference);
result = _factory.newEncryptedData(data);
break;
case CipherData.VALUE_TYPE:
CipherValue cipherValue = _factory.newCipherValue(value);
data = _factory.newCipherData(type);
data.setCipherValue(cipherValue);
result = _factory.newEncryptedData(data);
}
return (result);
| public EncryptedKey | createEncryptedKey(int type, java.lang.String value)Creates an EncryptedKey Element .
The newEncryptedData and newEncryptedKey methods create fairly complete
elements that are immediately useable. All the other create* methods
return bare elements that still need to be built upon.
An EncryptionMethod will still need to be added however
EncryptedKey result = null;
CipherData data = null;
switch (type) {
case CipherData.REFERENCE_TYPE:
CipherReference cipherReference = _factory.newCipherReference(
value);
data = _factory.newCipherData(type);
data.setCipherReference(cipherReference);
result = _factory.newEncryptedKey(data);
break;
case CipherData.VALUE_TYPE:
CipherValue cipherValue = _factory.newCipherValue(value);
data = _factory.newCipherData(type);
data.setCipherValue(cipherValue);
result = _factory.newEncryptedKey(data);
}
return (result);
| public EncryptionMethod | createEncryptionMethod(java.lang.String algorithm)Create an EncryptedMethod object
return (_factory.newEncryptionMethod(algorithm));
| public EncryptionProperties | createEncryptionProperties()Create an EncryptedProperties element
return (_factory.newEncryptionProperties());
| public EncryptionProperty | createEncryptionProperty()Create a new EncryptionProperty element
return (_factory.newEncryptionProperty());
| public ReferenceList | createReferenceList(int type)Create a new ReferenceList object
return (_factory.newReferenceList(type));
| public Transforms | createTransforms()Create a new Transforms object
Note: A context document must have been set
elsewhere (possibly via a call to doFinal). If not, use the
createTransforms(Document) method.
return (_factory.newTransforms());
| public Transforms | createTransforms(org.w3c.dom.Document doc)Create a new Transforms object
Because the handling of Transforms is currently done in the signature
code, the creation of a Transforms object requires a
context document.
return (_factory.newTransforms(doc));
| private org.w3c.dom.Document | decryptElement(org.w3c.dom.Element element)Decrypts EncryptedData in a single-part operation.
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Decrypting element...");
if(_cipherMode != DECRYPT_MODE)
logger.log(java.util.logging.Level.SEVERE, "XMLCipher unexpectedly not in DECRYPT_MODE...");
String octets;
try {
octets = new String(decryptToByteArray(element), "UTF-8");
} catch (UnsupportedEncodingException uee) {
throw new XMLEncryptionException("empty", uee);
}
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Decrypted octets:\n" + octets);
Node sourceParent = element.getParentNode();
DocumentFragment decryptedFragment =
_serializer.deserialize(octets, sourceParent);
// The de-serialiser returns a fragment whose children we need to
// take on.
if (sourceParent instanceof Document) {
// If this is a content decryption, this may have problems
_contextDocument.removeChild(_contextDocument.getDocumentElement());
_contextDocument.appendChild(decryptedFragment);
}
else {
sourceParent.replaceChild(decryptedFragment, element);
}
return (_contextDocument);
| private org.w3c.dom.Document | decryptElementContent(org.w3c.dom.Element element)
Element e = (Element) element.getElementsByTagNameNS(
EncryptionConstants.EncryptionSpecNS,
EncryptionConstants._TAG_ENCRYPTEDDATA).item(0);
if (null == e) {
throw new XMLEncryptionException("No EncryptedData child element.");
}
return (decryptElement(e));
| public java.security.Key | decryptKey(EncryptedKey encryptedKey, java.lang.String algorithm)Decrypt a key from a passed in EncryptedKey structure
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Decrypting key from previously loaded EncryptedKey...");
if(_cipherMode != UNWRAP_MODE)
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in UNWRAP_MODE...");
if (algorithm == null) {
throw new XMLEncryptionException("Cannot decrypt a key without knowing the algorithm");
}
if (_key == null) {
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Trying to find a KEK via key resolvers");
KeyInfo ki = encryptedKey.getKeyInfo();
if (ki != null) {
try {
_key = ki.getSecretKey();
}
catch (Exception e) {
}
}
if (_key == null) {
logger.log(java.util.logging.Level.SEVERE, "XMLCipher::decryptKey called without a KEK and cannot resolve");
throw new XMLEncryptionException("Unable to decrypt without a KEK");
}
}
// Obtain the encrypted octets
XMLCipherInput cipherInput = new XMLCipherInput(encryptedKey);
byte [] encryptedBytes = cipherInput.getBytes();
String jceKeyAlgorithm =
JCEMapper.getJCEKeyAlgorithmFromURI(algorithm);
Cipher c;
if (_contextCipher == null) {
// Now create the working cipher
String jceAlgorithm =
JCEMapper.translateURItoJCEID(
encryptedKey.getEncryptionMethod().getAlgorithm());
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "JCE Algorithm = " + jceAlgorithm);
try {
if (_requestedJCEProvider == null)
c = Cipher.getInstance(jceAlgorithm);
else
c = Cipher.getInstance(jceAlgorithm, _requestedJCEProvider);
} catch (NoSuchAlgorithmException nsae) {
throw new XMLEncryptionException("empty", nsae);
} catch (NoSuchProviderException nspre) {
throw new XMLEncryptionException("empty", nspre);
} catch (NoSuchPaddingException nspae) {
throw new XMLEncryptionException("empty", nspae);
}
} else {
c = _contextCipher;
}
Key ret;
try {
c.init(Cipher.UNWRAP_MODE, _key);
ret = c.unwrap(encryptedBytes, jceKeyAlgorithm, Cipher.SECRET_KEY);
} catch (InvalidKeyException ike) {
throw new XMLEncryptionException("empty", ike);
} catch (NoSuchAlgorithmException nsae) {
throw new XMLEncryptionException("empty", nsae);
}
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Decryption of key type " + algorithm + " OK");
return ret;
| public java.security.Key | decryptKey(EncryptedKey encryptedKey)Decrypt a key from a passed in EncryptedKey structure. This version
is used mainly internally, when the cipher already has an
EncryptedData loaded. The algorithm URI will be read from the
EncryptedData
return decryptKey(encryptedKey, _ed.getEncryptionMethod().getAlgorithm());
| public byte[] | decryptToByteArray(org.w3c.dom.Element element)Decrypt an EncryptedData element to a byte array
When passed in an EncryptedData node, returns the decryption
as a byte array.
Does not modify the source document
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Decrypting to ByteArray...");
if(_cipherMode != DECRYPT_MODE)
logger.log(java.util.logging.Level.SEVERE, "XMLCipher unexpectedly not in DECRYPT_MODE...");
EncryptedData encryptedData = _factory.newEncryptedData(element);
if (_key == null) {
KeyInfo ki = encryptedData.getKeyInfo();
if (ki != null) {
try {
// Add a EncryptedKey resolver
ki.registerInternalKeyResolver(
new EncryptedKeyResolver(encryptedData.
getEncryptionMethod().
getAlgorithm(),
_kek));
_key = ki.getSecretKey();
} catch (KeyResolverException kre) {
// We will throw in a second...
}
}
if (_key == null) {
logger.log(java.util.logging.Level.SEVERE, "XMLCipher::decryptElement called without a key and unable to resolve");
throw new XMLEncryptionException("encryption.nokey");
}
}
// Obtain the encrypted octets
XMLCipherInput cipherInput = new XMLCipherInput(encryptedData);
byte [] encryptedBytes = cipherInput.getBytes();
// Now create the working cipher
String jceAlgorithm =
JCEMapper.translateURItoJCEID(encryptedData.getEncryptionMethod().getAlgorithm());
Cipher c;
try {
if (_requestedJCEProvider == null)
c = Cipher.getInstance(jceAlgorithm);
else
c = Cipher.getInstance(jceAlgorithm, _requestedJCEProvider);
} catch (NoSuchAlgorithmException nsae) {
throw new XMLEncryptionException("empty", nsae);
} catch (NoSuchProviderException nspre) {
throw new XMLEncryptionException("empty", nspre);
} catch (NoSuchPaddingException nspae) {
throw new XMLEncryptionException("empty", nspae);
}
// Calculate the IV length and copy out
// For now, we only work with Block ciphers, so this will work.
// This should probably be put into the JCE mapper.
int ivLen = c.getBlockSize();
byte[] ivBytes = new byte[ivLen];
// You may be able to pass the entire piece in to IvParameterSpec
// and it will only take the first x bytes, but no way to be certain
// that this will work for every JCE provider, so lets copy the
// necessary bytes into a dedicated array.
System.arraycopy(encryptedBytes, 0, ivBytes, 0, ivLen);
IvParameterSpec iv = new IvParameterSpec(ivBytes);
try {
c.init(_cipherMode, _key, iv);
} catch (InvalidKeyException ike) {
throw new XMLEncryptionException("empty", ike);
} catch (InvalidAlgorithmParameterException iape) {
throw new XMLEncryptionException("empty", iape);
}
byte[] plainBytes;
try {
plainBytes = c.doFinal(encryptedBytes,
ivLen,
encryptedBytes.length - ivLen);
} catch (IllegalBlockSizeException ibse) {
throw new XMLEncryptionException("empty", ibse);
} catch (BadPaddingException bpe) {
throw new XMLEncryptionException("empty", bpe);
}
return (plainBytes);
| public org.w3c.dom.Document | doFinal(org.w3c.dom.Document context, org.w3c.dom.Document source)Process a DOM Document node. The processing depends on the
initialization parameters of {@link #init(int, Key) init()}.
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Processing source document...");
if(null == context)
logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null...");
if(null == source)
logger.log(java.util.logging.Level.SEVERE, "Source document unexpectedly null...");
_contextDocument = context;
Document result = null;
switch (_cipherMode) {
case DECRYPT_MODE:
result = decryptElement(source.getDocumentElement());
break;
case ENCRYPT_MODE:
result = encryptElement(source.getDocumentElement());
break;
case UNWRAP_MODE:
break;
case WRAP_MODE:
break;
default:
throw new XMLEncryptionException(
"empty", new IllegalStateException());
}
return (result);
| public org.w3c.dom.Document | doFinal(org.w3c.dom.Document context, org.w3c.dom.Element element)Process a DOM Element node. The processing depends on the
initialization parameters of {@link #init(int, Key) init()}.
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Processing source element...");
if(null == context)
logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null...");
if(null == element)
logger.log(java.util.logging.Level.SEVERE, "Source element unexpectedly null...");
_contextDocument = context;
Document result = null;
switch (_cipherMode) {
case DECRYPT_MODE:
result = decryptElement(element);
break;
case ENCRYPT_MODE:
result = encryptElement(element);
break;
case UNWRAP_MODE:
break;
case WRAP_MODE:
break;
default:
throw new XMLEncryptionException(
"empty", new IllegalStateException());
}
return (result);
| public org.w3c.dom.Document | doFinal(org.w3c.dom.Document context, org.w3c.dom.Element element, boolean content)Process the contents of a DOM Element node. The processing
depends on the initialization parameters of
{@link #init(int, Key) init()}.
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Processing source element...");
if(null == context)
logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null...");
if(null == element)
logger.log(java.util.logging.Level.SEVERE, "Source element unexpectedly null...");
_contextDocument = context;
Document result = null;
switch (_cipherMode) {
case DECRYPT_MODE:
if (content) {
result = decryptElementContent(element);
} else {
result = decryptElement(element);
}
break;
case ENCRYPT_MODE:
if (content) {
result = encryptElementContent(element);
} else {
result = encryptElement(element);
}
break;
case UNWRAP_MODE:
break;
case WRAP_MODE:
break;
default:
throw new XMLEncryptionException(
"empty", new IllegalStateException());
}
return (result);
| public EncryptedData | encryptData(org.w3c.dom.Document context, org.w3c.dom.Element element)Returns an EncryptedData interface. Use this operation if
you want to have full control over the contents of the
EncryptedData structure.
this does not change the source document in any way.
return encryptData(context, element, false);
| public EncryptedData | encryptData(org.w3c.dom.Document context, org.w3c.dom.Element element, boolean contentMode)Returns an EncryptedData interface. Use this operation if
you want to have full control over the contents of the
EncryptedData structure.
this does not change the source document in any way.
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypting element...");
if (null == context)
logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null...");
if (null == element)
logger.log(java.util.logging.Level.SEVERE, "Element unexpectedly null...");
if (_cipherMode != ENCRYPT_MODE)
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in ENCRYPT_MODE...");
_contextDocument = context;
if (_algorithm == null) {
throw new XMLEncryptionException("XMLCipher instance without transformation specified");
}
String serializedOctets = null;
if (contentMode) {
NodeList children = element.getChildNodes();
if ((null != children)) {
serializedOctets = _serializer.serialize(children);
} else {
Object exArgs[] = { "Element has no content." };
throw new XMLEncryptionException("empty", exArgs);
}
} else {
serializedOctets = _serializer.serialize(element);
}
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Serialized octets:\n" + serializedOctets);
byte[] encryptedBytes = null;
// Now create the working cipher if none was created already
Cipher c;
if (_contextCipher == null) {
String jceAlgorithm =
JCEMapper.translateURItoJCEID(_algorithm);
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "alg = " + jceAlgorithm);
try {
if (_requestedJCEProvider == null)
c = Cipher.getInstance(jceAlgorithm);
else
c = Cipher.getInstance(jceAlgorithm, _requestedJCEProvider);
} catch (NoSuchAlgorithmException nsae) {
throw new XMLEncryptionException("empty", nsae);
} catch (NoSuchProviderException nspre) {
throw new XMLEncryptionException("empty", nspre);
} catch (NoSuchPaddingException nspae) {
throw new XMLEncryptionException("empty", nspae);
}
}
else {
c = _contextCipher;
}
// Now perform the encryption
try {
// Should internally generate an IV
// todo - allow user to set an IV
c.init(_cipherMode, _key);
} catch (InvalidKeyException ike) {
throw new XMLEncryptionException("empty", ike);
}
try {
encryptedBytes =
c.doFinal(serializedOctets.getBytes("UTF-8"));
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Expected cipher.outputSize = " +
Integer.toString(c.getOutputSize(
serializedOctets.getBytes().length)));
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Actual cipher.outputSize = " +
Integer.toString(encryptedBytes.length));
} catch (IllegalStateException ise) {
throw new XMLEncryptionException("empty", ise);
} catch (IllegalBlockSizeException ibse) {
throw new XMLEncryptionException("empty", ibse);
} catch (BadPaddingException bpe) {
throw new XMLEncryptionException("empty", bpe);
} catch (UnsupportedEncodingException uee) {
throw new XMLEncryptionException("empty", uee);
}
// Now build up to a properly XML Encryption encoded octet stream
// IvParameterSpec iv;
byte[] iv = c.getIV();
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 = Base64.encode(finalEncryptedBytes);
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypted octets:\n" + base64EncodedEncryptedOctets);
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypted octets length = " +
base64EncodedEncryptedOctets.length());
try {
CipherData cd = _ed.getCipherData();
CipherValue cv = cd.getCipherValue();
// cv.setValue(base64EncodedEncryptedOctets.getBytes());
cv.setValue(base64EncodedEncryptedOctets);
if (contentMode) {
_ed.setType(
new URI(EncryptionConstants.TYPE_CONTENT).toString());
} else {
_ed.setType(
new URI(EncryptionConstants.TYPE_ELEMENT).toString());
}
EncryptionMethod method =
_factory.newEncryptionMethod(new URI(_algorithm).toString());
_ed.setEncryptionMethod(method);
} catch (URI.MalformedURIException mfue) {
throw new XMLEncryptionException("empty", mfue);
}
return (_ed);
| public EncryptedData | encryptData(org.w3c.dom.Document context, byte[] serializedOctets, boolean contentMode)
logger.log(java.util.logging.Level.FINE, "Encrypting element...");
if (null == context)
logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null...");
if (null == serializedOctets)
logger.log(java.util.logging.Level.SEVERE, "Canonicalized Data is unexpectedly null...");
if (_cipherMode != ENCRYPT_MODE)
logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in ENCRYPT_MODE...");
_contextDocument = context;
if (_algorithm == null) {
throw new XMLEncryptionException("XMLCipher instance without transformation specified");
}
logger.log(java.util.logging.Level.FINE, "Serialized octets:\n" + serializedOctets);
byte[] encryptedBytes = null;
// Now create the working cipher if none was created already
Cipher c;
if (_contextCipher == null) {
String jceAlgorithm =
JCEMapper.translateURItoJCEID(_algorithm);
logger.log(java.util.logging.Level.FINE, "alg = " + jceAlgorithm);
try {
if (_requestedJCEProvider == null)
c = Cipher.getInstance(jceAlgorithm);
else
c = Cipher.getInstance(jceAlgorithm, _requestedJCEProvider);
} catch (NoSuchAlgorithmException nsae) {
throw new XMLEncryptionException("empty", nsae);
} catch (NoSuchProviderException nspre) {
throw new XMLEncryptionException("empty", nspre);
} catch (NoSuchPaddingException nspae) {
throw new XMLEncryptionException("empty", nspae);
}
} else {
c = _contextCipher;
}
// Now perform the encryption
try {
// Should internally generate an IV
// todo - allow user to set an IV
c.init(_cipherMode, _key);
} catch (InvalidKeyException ike) {
throw new XMLEncryptionException("empty", ike);
}
try {
encryptedBytes =
c.doFinal(serializedOctets);
logger.log(java.util.logging.Level.FINE, "Expected cipher.outputSize = " +
Integer.toString(c.getOutputSize(
serializedOctets.length)));
logger.log(java.util.logging.Level.FINE, "Actual cipher.outputSize = " +
Integer.toString(encryptedBytes.length));
} catch (IllegalStateException ise) {
throw new XMLEncryptionException("empty", ise);
} catch (IllegalBlockSizeException ibse) {
throw new XMLEncryptionException("empty", ibse);
} catch (BadPaddingException bpe) {
throw new XMLEncryptionException("empty", bpe);
} catch (Exception uee) {
throw new XMLEncryptionException("empty", uee);
}
// Now build up to a properly XML Encryption encoded octet stream
// IvParameterSpec iv;
byte[] iv = c.getIV();
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 = Base64.encode(finalEncryptedBytes);
logger.log(java.util.logging.Level.FINE, "Encrypted octets:\n" + base64EncodedEncryptedOctets);
logger.log(java.util.logging.Level.FINE, "Encrypted octets length = " +
base64EncodedEncryptedOctets.length());
try {
CipherData cd = _ed.getCipherData();
CipherValue cv = cd.getCipherValue();
// cv.setValue(base64EncodedEncryptedOctets.getBytes());
cv.setValue(base64EncodedEncryptedOctets);
if (contentMode) {
_ed.setType(
new URI(EncryptionConstants.TYPE_CONTENT).toString());
} else {
_ed.setType(
new URI(EncryptionConstants.TYPE_ELEMENT).toString());
}
EncryptionMethod method =
_factory.newEncryptionMethod(new URI(_algorithm).toString());
_ed.setEncryptionMethod(method);
} catch (URI.MalformedURIException mfue) {
throw new XMLEncryptionException("empty", mfue);
}
return (_ed);
| private org.w3c.dom.Document | encryptElement(org.w3c.dom.Element element)Encrypts an Element and replaces it with its encrypted
counterpart in the context Document , that is, the
Document specified when one calls
{@link #getInstance(String) getInstance}.
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypting element...");
if(null == element)
logger.log(java.util.logging.Level.SEVERE, "Element unexpectedly null...");
if(_cipherMode != ENCRYPT_MODE)
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in ENCRYPT_MODE...");
if (_algorithm == null) {
throw new XMLEncryptionException("XMLCipher instance without transformation specified");
}
encryptData(_contextDocument, element, false);
Element encryptedElement = _factory.toElement(_ed);
Node sourceParent = element.getParentNode();
sourceParent.replaceChild(encryptedElement, element);
return (_contextDocument);
| private org.w3c.dom.Document | encryptElementContent(org.w3c.dom.Element element)Encrypts a NodeList (the contents of an
Element ) and replaces its parent Element 's
content with this the resulting EncryptedType within the
context Document , that is, the Document
specified when one calls
{@link #getInstance(String) getInstance}.
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypting element content...");
if(null == element)
logger.log(java.util.logging.Level.SEVERE, "Element unexpectedly null...");
if(_cipherMode != ENCRYPT_MODE)
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in ENCRYPT_MODE...");
if (_algorithm == null) {
throw new XMLEncryptionException("XMLCipher instance without transformation specified");
}
encryptData(_contextDocument, element, true);
Element encryptedElement = _factory.toElement(_ed);
removeContent(element);
element.appendChild(encryptedElement);
return (_contextDocument);
| public EncryptedKey | encryptKey(org.w3c.dom.Document doc, java.security.Key key)Encrypts a key to an EncryptedKey structure
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypting key ...");
if(null == key)
logger.log(java.util.logging.Level.SEVERE, "Key unexpectedly null...");
if(_cipherMode != WRAP_MODE)
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in WRAP_MODE...");
if (_algorithm == null) {
throw new XMLEncryptionException("XMLCipher instance without transformation specified");
}
_contextDocument = doc;
byte[] encryptedBytes = null;
Cipher c;
if (_contextCipher == null) {
// Now create the working cipher
String jceAlgorithm =
JCEMapper.translateURItoJCEID(_algorithm);
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "alg = " + jceAlgorithm);
try {
if (_requestedJCEProvider == null)
c = Cipher.getInstance(jceAlgorithm);
else
c = Cipher.getInstance(jceAlgorithm, _requestedJCEProvider);
} catch (NoSuchAlgorithmException nsae) {
throw new XMLEncryptionException("empty", nsae);
} catch (NoSuchProviderException nspre) {
throw new XMLEncryptionException("empty", nspre);
} catch (NoSuchPaddingException nspae) {
throw new XMLEncryptionException("empty", nspae);
}
} else {
c = _contextCipher;
}
// Now perform the encryption
try {
// Should internally generate an IV
// todo - allow user to set an IV
c.init(Cipher.WRAP_MODE, _key);
encryptedBytes = c.wrap(key);
} catch (InvalidKeyException ike) {
throw new XMLEncryptionException("empty", ike);
} catch (IllegalBlockSizeException ibse) {
throw new XMLEncryptionException("empty", ibse);
}
String base64EncodedEncryptedOctets = Base64.encode(encryptedBytes);
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypted key octets:\n" + base64EncodedEncryptedOctets);
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypted key octets length = " +
base64EncodedEncryptedOctets.length());
CipherValue cv = _ek.getCipherData().getCipherValue();
cv.setValue(base64EncodedEncryptedOctets);
try {
EncryptionMethod method = _factory.newEncryptionMethod(
new URI(_algorithm).toString());
_ek.setEncryptionMethod(method);
} catch (URI.MalformedURIException mfue) {
throw new XMLEncryptionException("empty", mfue);
}
return _ek;
| public EncryptedData | getEncryptedData()Get the EncryptedData being build
Returns the EncryptedData being built during an ENCRYPT operation.
This can then be used by applications to add KeyInfo elements and
set other parameters.
// Sanity checks
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Returning EncryptedData");
return _ed;
| public EncryptedKey | getEncryptedKey()Get the EncryptedData being build
Returns the EncryptedData being built during an ENCRYPT operation.
This can then be used by applications to add KeyInfo elements and
set other parameters.
// Sanity checks
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Returning EncryptedKey");
return _ek;
| public static com.sun.org.apache.xml.internal.security.encryption.XMLCipher | getInstance(java.lang.String transformation)Returns an XMLCipher that implements the specified
transformation and operates on the specified context document.
If the default provider package supplies an implementation of the
requested transformation, an instance of Cipher containing that
implementation is returned. If the transformation is not available in
the default provider package, other provider packages are searched.
NOTE1: The transformation name does not follow the same
pattern as that oulined in the Java Cryptography Extension Reference
Guide but rather that specified by the XML Encryption Syntax and
Processing document. The rational behind this is to make it easier for a
novice at writing Java Encryption software to use the library.
NOTE2: getInstance() does not follow the
same pattern regarding exceptional conditions as that used in
javax.crypto.Cipher . Instead, it only throws an
XMLEncryptionException which wraps an underlying exception.
The stack trace from the exception should be self explanitory.
// sanity checks
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Getting XMLCipher...");
if (null == transformation)
logger.log(java.util.logging.Level.SEVERE, "Transformation unexpectedly null...");
if(!isValidEncryptionAlgorithm(transformation))
logger.log(java.util.logging.Level.WARNING, "Algorithm non-standard, expected one of " + ENC_ALGORITHMS);
XMLCipher instance = new XMLCipher();
instance._algorithm = transformation;
instance._key = null;
instance._kek = null;
/* Create a canonicaliser - used when serialising DOM to octets
* prior to encryption (and for the reverse) */
try {
instance._canon = Canonicalizer.getInstance
(Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);
} catch (InvalidCanonicalizerException ice) {
throw new XMLEncryptionException("empty", ice);
}
String jceAlgorithm = JCEMapper.translateURItoJCEID(transformation);
try {
instance._contextCipher = Cipher.getInstance(jceAlgorithm);
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "cihper.algoritm = " +
instance._contextCipher.getAlgorithm());
} catch (NoSuchAlgorithmException nsae) {
throw new XMLEncryptionException("empty", nsae);
} catch (NoSuchPaddingException nspe) {
throw new XMLEncryptionException("empty", nspe);
}
return (instance);
| public static com.sun.org.apache.xml.internal.security.encryption.XMLCipher | getInstance(java.lang.String transformation, javax.crypto.Cipher cipher)
// sanity checks
logger.log(java.util.logging.Level.FINE, "Getting XMLCipher...");
if (null == transformation)
logger.log(java.util.logging.Level.SEVERE, "Transformation unexpectedly null...");
if(!isValidEncryptionAlgorithm(transformation))
logger.log(java.util.logging.Level.WARNING, "Algorithm non-standard, expected one of " + ENC_ALGORITHMS);
XMLCipher instance = new XMLCipher();
instance._algorithm = transformation;
instance._key = null;
instance._kek = null;
/* Create a canonicaliser - used when serialising DOM to octets
* prior to encryption (and for the reverse) */
try {
instance._canon = Canonicalizer.getInstance
(Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);
} catch (InvalidCanonicalizerException ice) {
throw new XMLEncryptionException("empty", ice);
}
String jceAlgorithm = JCEMapper.translateURItoJCEID(transformation);
try {
instance._contextCipher = cipher;
//Cipher.getInstance(jceAlgorithm);
logger.log(java.util.logging.Level.FINE, "cihper.algoritm = " +
instance._contextCipher.getAlgorithm());
}catch(Exception ex) {
throw new XMLEncryptionException("empty", ex);
}
return (instance);
| public static com.sun.org.apache.xml.internal.security.encryption.XMLCipher | getInstance(java.lang.String transformation, java.lang.String canon)Returns an XMLCipher that implements the specified
transformation, operates on the specified context document and serializes
the document with the specified canonicalization algorithm before it
encrypts the document.
XMLCipher instance = XMLCipher.getInstance(transformation);
if (canon != null) {
try {
instance._canon = Canonicalizer.getInstance(canon);
} catch (InvalidCanonicalizerException ice) {
throw new XMLEncryptionException("empty", ice);
}
}
return instance;
| public static com.sun.org.apache.xml.internal.security.encryption.XMLCipher | getInstance()Returns an XMLCipher that implements no specific
transformation, and can therefore only be used for decrypt or
unwrap operations where the encryption method is defined in the
EncryptionMethod element.
// sanity checks
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Getting XMLCipher for no transformation...");
XMLCipher instance = new XMLCipher();
instance._algorithm = null;
instance._requestedJCEProvider = null;
instance._key = null;
instance._kek = null;
instance._contextCipher = null;
/* Create a canonicaliser - used when serialising DOM to octets
* prior to encryption (and for the reverse) */
try {
instance._canon = Canonicalizer.getInstance
(Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);
} catch (InvalidCanonicalizerException ice) {
throw new XMLEncryptionException("empty", ice);
}
return (instance);
| public static com.sun.org.apache.xml.internal.security.encryption.XMLCipher | getProviderInstance(java.lang.String transformation, java.lang.String provider)Returns an XMLCipher that implements the specified
transformation and operates on the specified context document.
// sanity checks
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Getting XMLCipher...");
if (null == transformation)
logger.log(java.util.logging.Level.SEVERE, "Transformation unexpectedly null...");
if(null == provider)
logger.log(java.util.logging.Level.SEVERE, "Provider unexpectedly null..");
if("" == provider)
logger.log(java.util.logging.Level.SEVERE, "Provider's value unexpectedly not specified...");
if(!isValidEncryptionAlgorithm(transformation))
logger.log(java.util.logging.Level.WARNING, "Algorithm non-standard, expected one of " + ENC_ALGORITHMS);
XMLCipher instance = new XMLCipher();
instance._algorithm = transformation;
instance._requestedJCEProvider = provider;
instance._key = null;
instance._kek = null;
/* Create a canonicaliser - used when serialising DOM to octets
* prior to encryption (and for the reverse) */
try {
instance._canon = Canonicalizer.getInstance
(Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);
} catch (InvalidCanonicalizerException ice) {
throw new XMLEncryptionException("empty", ice);
}
try {
String jceAlgorithm =
JCEMapper.translateURItoJCEID(transformation);
instance._contextCipher = Cipher.getInstance(jceAlgorithm, provider);
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "cipher._algorithm = " +
instance._contextCipher.getAlgorithm());
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "provider.name = " + provider);
} catch (NoSuchAlgorithmException nsae) {
throw new XMLEncryptionException("empty", nsae);
} catch (NoSuchProviderException nspre) {
throw new XMLEncryptionException("empty", nspre);
} catch (NoSuchPaddingException nspe) {
throw new XMLEncryptionException("empty", nspe);
}
return (instance);
| public static com.sun.org.apache.xml.internal.security.encryption.XMLCipher | getProviderInstance(java.lang.String transformation, java.lang.String provider, java.lang.String canon)Returns an XMLCipher that implements the specified
transformation, operates on the specified context document and serializes
the document with the specified canonicalization algorithm before it
encrypts the document.
XMLCipher instance = XMLCipher.getProviderInstance(transformation, provider);
if (canon != null) {
try {
instance._canon = Canonicalizer.getInstance(canon);
} catch (InvalidCanonicalizerException ice) {
throw new XMLEncryptionException("empty", ice);
}
}
return instance;
| public static com.sun.org.apache.xml.internal.security.encryption.XMLCipher | getProviderInstance(java.lang.String provider)Returns an XMLCipher that implements no specific
transformation, and can therefore only be used for decrypt or
unwrap operations where the encryption method is defined in the
EncryptionMethod element.
Allows the caller to specify a provider that will be used for
cryptographic operations.
// sanity checks
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Getting XMLCipher, provider but no transformation");
if(null == provider)
logger.log(java.util.logging.Level.SEVERE, "Provider unexpectedly null..");
if("" == provider)
logger.log(java.util.logging.Level.SEVERE, "Provider's value unexpectedly not specified...");
XMLCipher instance = new XMLCipher();
instance._algorithm = null;
instance._requestedJCEProvider = provider;
instance._key = null;
instance._kek = null;
instance._contextCipher = null;
try {
instance._canon = Canonicalizer.getInstance
(Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);
} catch (InvalidCanonicalizerException ice) {
throw new XMLEncryptionException("empty", ice);
}
return (instance);
| public void | init(int opmode, java.security.Key key)Initializes this cipher with a key.
The cipher is initialized for one of the following four operations:
encryption, decryption, key wrapping or key unwrapping, depending on the
value of opmode.
For WRAP and ENCRYPT modes, this also initialises the internal
EncryptedKey or EncryptedData (with a CipherValue)
structure that will be used during the ensuing operations. This
can be obtained (in order to modify KeyInfo elements etc. prior to
finalising the encryption) by calling
{@link #getEncryptedData} or {@link #getEncryptedKey}.
// sanity checks
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Initializing XMLCipher...");
_ek = null;
_ed = null;
switch (opmode) {
case ENCRYPT_MODE :
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "opmode = ENCRYPT_MODE");
_ed = createEncryptedData(CipherData.VALUE_TYPE, "NO VALUE YET");
break;
case DECRYPT_MODE :
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "opmode = DECRYPT_MODE");
break;
case WRAP_MODE :
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "opmode = WRAP_MODE");
_ek = createEncryptedKey(CipherData.VALUE_TYPE, "NO VALUE YET");
break;
case UNWRAP_MODE :
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "opmode = UNWRAP_MODE");
break;
default :
logger.log(java.util.logging.Level.SEVERE, "Mode unexpectedly invalid");
throw new XMLEncryptionException("Invalid mode in init");
}
_cipherMode = opmode;
_key = key;
| private static boolean | isValidEncryptionAlgorithm(java.lang.String algorithm)Checks to ensure that the supplied algorithm is valid.
boolean result = (
algorithm.equals(TRIPLEDES) ||
algorithm.equals(AES_128) ||
algorithm.equals(AES_256) ||
algorithm.equals(AES_192) ||
algorithm.equals(RSA_v1dot5) ||
algorithm.equals(RSA_OAEP) ||
algorithm.equals(TRIPLEDES_KeyWrap) ||
algorithm.equals(AES_128_KeyWrap) ||
algorithm.equals(AES_256_KeyWrap) ||
algorithm.equals(AES_192_KeyWrap)
);
return (result);
| public EncryptedData | loadEncryptedData(org.w3c.dom.Document context, org.w3c.dom.Element element)Returns an EncryptedData interface. Use this operation if
you want to load an EncryptedData structure from a DOM
structure and manipulate the contents
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Loading encrypted element...");
if(null == context)
logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null...");
if(null == element)
logger.log(java.util.logging.Level.SEVERE, "Element unexpectedly null...");
if(_cipherMode != DECRYPT_MODE)
logger.log(java.util.logging.Level.SEVERE, "XMLCipher unexpectedly not in DECRYPT_MODE...");
_contextDocument = context;
_ed = _factory.newEncryptedData(element);
return (_ed);
| public EncryptedKey | loadEncryptedKey(org.w3c.dom.Document context, org.w3c.dom.Element element)Returns an EncryptedKey interface. Use this operation if
you want to load an EncryptedKey structure from a DOM
structure and manipulate the contents.
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Loading encrypted key...");
if(null == context)
logger.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null...");
if(null == element)
logger.log(java.util.logging.Level.SEVERE, "Element unexpectedly null...");
if(_cipherMode != UNWRAP_MODE && _cipherMode != DECRYPT_MODE)
if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in UNWRAP_MODE or DECRYPT_MODE...");
_contextDocument = context;
_ek = _factory.newEncryptedKey(element);
return (_ek);
| public EncryptedKey | loadEncryptedKey(org.w3c.dom.Element element)Returns an EncryptedKey interface. Use this operation if
you want to load an EncryptedKey structure from a DOM
structure and manipulate the contents.
Assumes that the context document is the document that owns the element
return (loadEncryptedKey(element.getOwnerDocument(), element));
| public org.w3c.dom.Element | martial(EncryptedData encryptedData)Martial an EncryptedData
Takes an EncryptedData object and returns a DOM Element that
represents the appropriate EncryptedData
Note: This should only be used in cases where the context
document has been passed in via a call to doFinal.
return (_factory.toElement (encryptedData));
| public org.w3c.dom.Element | martial(EncryptedKey encryptedKey)Martial an EncryptedKey
Takes an EncryptedKey object and returns a DOM Element that
represents the appropriate EncryptedKey
Note: This should only be used in cases where the context
document has been passed in via a call to doFinal.
return (_factory.toElement (encryptedKey));
| public org.w3c.dom.Element | martial(org.w3c.dom.Document context, EncryptedData encryptedData)Martial an EncryptedData
Takes an EncryptedData object and returns a DOM Element that
represents the appropriate EncryptedData
_contextDocument = context;
return (_factory.toElement (encryptedData));
| public org.w3c.dom.Element | martial(org.w3c.dom.Document context, EncryptedKey encryptedKey)Martial an EncryptedKey
Takes an EncryptedKey object and returns a DOM Element that
represents the appropriate EncryptedKey
_contextDocument = context;
return (_factory.toElement (encryptedKey));
| private void | removeContent(org.w3c.dom.Node node)Removes the contents of a Node .
NodeList list = node.getChildNodes();
if (list.getLength() > 0) {
Node n = list.item(0);
if (null != n) {
n.getParentNode().removeChild(n);
}
removeContent(node);
}
| public void | setKEK(java.security.Key kek)Set a Key Encryption Key.
The Key Encryption Key (KEK) is used for encrypting/decrypting
EncryptedKey elements. By setting this separately, the XMLCipher
class can know whether a key applies to the data part or wrapped key
part of an encrypted object.
_kek = kek;
|
|