可能是这样做的更好方法(如果是这样,请告诉我)但这是我想出的。从这个样本中解决了这个问题
读取输入
假设你有一个 InputStream 或 InputSource:
Document document = XMLUtils.read(is);
// specific to my case, lookup the RSA key value node, and from there go to the parents
NodeList keyInfoList = document.getElementsByTagNameNS(XMLSignature.XMLNS, Constants._TAG_RSAKEYVALUE);
assert keyInfoList.getLength() == 1;
DOMStructure domStructure = new DOMStructure(keyInfoList.item(0).getParentNode().getParentNode());
// from here on it's generic again
KeyInfo keyInfo = KeyInfoFactory.getInstance("DOM").unmarshalKeyInfo(domStructure);
KeyValue keyValue = (KeyValue) keyInfo.getContent().get(0);
publicKey = keyValue.getPublicKey();
加密文档
要获取加密文档,需要执行以下步骤:
- 生成密钥
- 使用公钥加密该密钥
- 加密文档
生成密钥
KeyGenerator keygen = KeyGenerator.getInstance("AES");
keygen.init(128);
secretKey = keygen.generateKey();
加密密钥
XMLCipher kekCipher = XMLCipher.getInstance(XMLCipher.RSA_OAEP);
kekCipher.init(XMLCipher.WRAP_MODE, publicKey);
EncryptedKey encryptedKey = kekCipher.encryptKey(inputDocument, secretKey);
加密文档
XMLCipher cipher = XMLCipher.getInstance(XMLCipher.AES_128);
cipher.init(XMLCipher.ENCRYPT_MODE, secretKey);
// Create a KeyInfo for the EncryptedData
EncryptedData encryptedData = cipher.getEncryptedData();
org.apache.xml.security.keys.KeyInfo keyInfo = new org.apache.xml.security.keys.KeyInfo(inputDocument);
keyInfo.add(encryptedKey);
encryptedData.setKeyInfo(keyInfo);
Document result = cipher.doFinal(inputDocument, inputDocument);
可选的
// output the result to a stream:
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
XMLUtils.outputDOM(result, baos, true);
}
// add key info to the encrypted key
org.apache.xml.security.keys.KeyInfo encryptedKeyKeyInfo = new org.apache.xml.security.keys.KeyInfo(document);
// not sure the following is needed
encryptedKeyKeyInfo.getElement()
.setAttributeNS(
"http://www.w3.org/2000/xmlns/",
"xmlns:dsig",
"http://www.w3.org/2000/09/xmldsig#");
encryptedKey.setKeyInfo(encryptedKeyKeyInfo);
encryptedKeyKeyInfo.add(publicKey);
// encrypt a specific node rather than the whole document
NodeList nodeList = document.getElementsByTagNameNS(ns, qName.getLocalPart());
// not sure if this'll work for embedded nodes
for (int i = 0, n = nodeList.getLength(); i < n; i++) {
Element elementToEncrypt = (Element) nodeList.item(i);
document = cipher.doFinal(document, elementToEncrypt, false);
// last parameter says to either encrypt the children of 'elementToEncrypt'
// or the element itself
}