xmlcipher.java
来自「JAVA 所有包」· Java 代码 · 共 1,715 行 · 第 1/5 页
JAVA
1,715 行
XMLEncryptionException { 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; } /** * 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 * * @param encryptedKey Previously loaded EncryptedKey that needs * to be decrypted. * @return a key corresponding to the give type * @throws XMLEncryptionException */ public Key decryptKey(EncryptedKey encryptedKey) throws XMLEncryptionException { return decryptKey(encryptedKey, _ed.getEncryptionMethod().getAlgorithm()); } /** * Removes the contents of a <code>Node</code>. * * @param node the <code>Node</code> to clear. */ private void removeContent(Node node) { NodeList list = node.getChildNodes(); if (list.getLength() > 0) { Node n = list.item(0); if (null != n) { n.getParentNode().removeChild(n); } removeContent(node); } } /** * Decrypts <code>EncryptedData</code> in a single-part operation. * * @param element the <code>EncryptedData</code> to decrypt. * @return the <code>Node</code> as a result of the decrypt operation. * @throws XMLEncryptionException */ private Document decryptElement(Element element) throws XMLEncryptionException { 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); } /** * * @param element * @return * @throws XMLEncryptionException */ private Document decryptElementContent(Element element) throws XMLEncryptionException { 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)); } /** * 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 * @param element * @return * @throws XMLEncryptionException */ public byte[] decryptToByteArray(Element element) throws XMLEncryptionException { 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); } /* * Expose the interface for creating XML Encryption objects */ /** * Creates an <code>EncryptedData</code> <code>Element</code>. * * 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. *<p> * An EncryptionMethod will still need to be added however * * @param type Either REFERENCE_TYPE or VALUE_TYPE - defines what kind of * CipherData this EncryptedData will contain. * @param value the Base 64 encoded, encrypted text to wrap in the * <code>EncryptedData</code> or the URI to set in the CipherReference * (usage will depend on the <code>type</code> * @return the <code>EncryptedData</code> <code>Element</code>. * * <!-- * <EncryptedData Id[OPT] Type[OPT] MimeType[OPT] Encoding[OPT]> * <EncryptionMethod/>[OPT] * <ds:KeyInfo>[OPT] * <EncryptedKey/>[OPT] * <AgreementMethod/>[OPT] * <ds:KeyName/>[OPT] * <ds:RetrievalMethod/>[OPT] * <ds:[MUL]/>[OPT] * </ds:KeyInfo> * <CipherData>[MAN] * <CipherValue/> XOR <CipherReference/> * </CipherData> * <EncryptionProperties/>[OPT] * </EncryptedData> * --> * @throws XMLEncryptionException */ public EncryptedData createEncryptedData(int type, String value) throws XMLEncryptionException { EncryptedData result = null; CipherData data = null; switch (type) { case CipherData.REFERENCE_TYPE: CipherReference cipherReference = _factory.newCipherReference( value); data = _factory.new
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?