关于避难所的例子或教程(Java)?

examples or tutorials about santuario (Java)?

我需要加密一个 XML,而 Santuario 看起来是完成这项工作的工具。问题是,我不知道如何开始使用它。

从常见问题解答(似乎真的过时了),我得到了 https://svn.apache.org/repos/asf/santuario/xml-security-java/trunk/samples/org/apache/xml/security/samples/,但那是相当空的。

一开始我有一个传入的 public 密钥,我想阅读它,所以像这样:

<?xml version="1.0" encoding="UTF-8"?>
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <ds:KeyValue>
    <ds:RSAKeyValue>
      <ds:Modulus>6sNhgtNVksGD4ZK1rW2iiGO11O/BzEIZazovnMK37y3RVvvjmv1z44uA505gyyUTziCntHV9tONm&#13;
J11bH4koqqJQFZPXuKAyuu9eR3W/pZ4EGBMMIVH2aqSOsPMTI5K9l2YOW8fAoEZQtYVWsCrygOyc&#13;
tBiamJZRJ+AKFZCIY5E=</ds:Modulus>
      <ds:Exponent>AQAB</ds:Exponent>
    </ds:RSAKeyValue>
  </ds:KeyValue>
</ds:KeyInfo>

我有点希望使用 JAXB 将其读入 org.apache.xml.security.keys.KeyInfo,但它没有空操作构造函数,所以这行不通。如何解析这样的文档以获得 KeyInfo 对象? (我试图避免 DocumentBuilderFactory 等人进行低级处理,但如果需要会这样做)

然后我需要使用这个 public 密钥来加密生成的密钥 (AES-128),然后我用它来加密 XML 文档。我需要再次将所有内容输出为 XML。我希望 lib 也有这方面的实用程序?

这可能是更好的方法(如果是这样,请告诉我)但这是我想到的。从这个 sample

算出来的

读取输入

假设您有一个 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();

正在加密文档

要获取加密文档,需要执行以下步骤:

  1. 生成密钥
  2. 使用 public 密钥加密该密钥
    • 可选择添加用于加密的输入密钥
  3. 加密文档
    • 或文档中的任何节点

生成密钥

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
}