OpenSAML:在encryptedassertion中包含X509证书



我正在尝试使用OpenSAML和ComponentSpace作为SP实现IDP发起的SSO。SP被配置为接受带有加密断言的SAMLResponse。

我能够加密断言,但SP要求我在EncryptedData中的KeyInfo中包含X509证书。

是否可以使用OpenSAML?如果是,你能告诉我如何做到这一点吗?

SP期望:

<saml:EncryptedAssertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns="http://www.w3.org/2001/04/xmlenc#">
  <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
  <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
    <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
      <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" />
      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
        <X509Data>
          <X509Certificate>......</X509Certificate>
        </X509Data>
      </KeyInfo>
      <CipherData>
        <CipherValue>......</CipherValue>
      </CipherData>
    </EncryptedKey>
  </KeyInfo>
  <CipherData>
    <CipherValue>......</CipherValue>
  </CipherData>
</EncryptedData>

我能生成的:

<EncryptedAssertion>
    <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" Type="http://www.w3.org/2001/04/xmlenc#Element">
        <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
        <dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
            <xenc:EncryptedKey>
                <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
                <xenc:CipherData>
                    <xenc:CipherValue>......</xenc:CipherValue>
                </xenc:CipherData>
            </xenc:EncryptedKey>
        </dsig:KeyInfo>
        <xenc:CipherData>
            <xenc:CipherValue>......</xenc:CipherValue>
        </xenc:CipherData>
    </xenc:EncryptedData>
</EncryptedAssertion>

查看http://ideone.com/p4Bhy9中的signSamlResponseObject2()方法。

public void signSamlResponseObject2() {
        try {
            String keyStoreFileName = "/WEB-INF/classes/saml-data/keystore.jks";
            InputStream fis = getServletContext().getResource(keyStoreFileName)
                    .openStream();
            KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
            ks.load(fis, "abc123456*".toCharArray());
            fis.close();
            // Get Private Key Entry From keystore
            KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) ks
                    .getEntry("zohosso", new KeyStore.PasswordProtection(
                            "abc123456*".toCharArray()));
            PrivateKey privKey = pkEntry.getPrivateKey();
            PublicKey pubKey = ks.getCertificate("zohosso").getPublicKey();
            X509Certificate cert = (X509Certificate) ks
                    .getCertificate("zohosso");
            /*
             * // Getting x509 Certificate from the keystore directly.
             * 
             * KeyStore.TrustedCertificateEntry certEntry =
             * (KeyStore.TrustedCertificateEntry) ks .getEntry("zohosso", new
             * KeyStore.PasswordProtection( "abc123456*".toCharArray()));
             * 
             * X509Certificate cert = (X509Certificate)
             * certEntry.getTrustedCertificate();
             */
            // Create a DOM XMLSignatureFactory that will be used to generate
            // the
            // enveloped signature.
            // String providerName =
            // System.getProperty("jsr105Provider",JSR_105_PROVIDER);
            XMLSignatureFactory sigFactory = XMLSignatureFactory
                    .getInstance("DOM");
            // Create a Reference to the enveloped document (we are
            // signing the whole document, so a URI of "" signifies that) and
            // also specify the SHA1 digest algorithm and the ENVELOPED
            // Transform.
            List envelopedTransform = Collections.singletonList(sigFactory
                    .newTransform(Transform.ENVELOPED,
                            (TransformParameterSpec) null));
            Reference ref = sigFactory.newReference("",
                    sigFactory.newDigestMethod(DigestMethod.SHA1, null),
                    envelopedTransform, null, null);
            SignatureMethod signatureMethod = sigFactory.newSignatureMethod(
                    SignatureMethod.DSA_SHA1, null);
            CanonicalizationMethod canonicalizationMethod = sigFactory
                    .newCanonicalizationMethod(
                            CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
                            (C14NMethodParameterSpec) null);
            // Create the SignedInfo
            SignedInfo signedInfo = sigFactory.newSignedInfo(
                    canonicalizationMethod, signatureMethod,
                    Collections.singletonList(ref));
            // Create a KeyValue containing the DSA PublicKey
            KeyInfoFactory keyInfoFactory = sigFactory.getKeyInfoFactory();
            KeyValue keyValuePair = keyInfoFactory.newKeyValue(pubKey);

            // Creating the x509 certificate data from Certificate object ( cert )
            List x509 = new ArrayList();
            x509.add(cert);
            X509Data x509Data = keyInfoFactory.newX509Data(x509);
            // Create a KeyInfo and add the KeyValue to it
            // keyInfoItems.add(Collections.singletonList(keyValuePair));
            // Adding the certificate data and the key value pair to the keyInfo 

            List keyInfoItems = new ArrayList();
            keyInfoItems.add(x509Data);
            keyInfoItems.add(keyValuePair);
            KeyInfo keyInfo = keyInfoFactory.newKeyInfo(keyInfoItems);

            // Building the org.jdom.Document object from the samlResponse
            // string
            // ------------------------------------------------------------------
            SAXBuilder builder = new SAXBuilder();
            org.jdom.Document doc = builder.build(new ByteArrayInputStream(
                    strResponseXML.getBytes()));
            // ------------------------------------------------------------------
            // Convert the rootElement extracted from the doc to w3cElement
            // ------------------------------------------------------------------
            org.jdom.Element docRootElement = doc.getRootElement();
            doc = docRootElement.getDocument();
            XMLOutputter xmlOutputter = new XMLOutputter();
            StringWriter elemStrWriter = new StringWriter();
            xmlOutputter.output(doc, elemStrWriter);
            byte[] xmlBytes = elemStrWriter.toString().getBytes();
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            org.w3c.dom.Element w3cElement = dbf.newDocumentBuilder()
                    .parse(new ByteArrayInputStream(xmlBytes))
                    .getDocumentElement();
            // --------------------------------------------------------------------
            // Create a DOMSignContext and specify the DSA PrivateKey and
            // location of the resulting XMLSignature's parent element
            DOMSignContext dsc = new DOMSignContext(privKey, w3cElement);
            // compute the correct location to insert the signature xml
            // (location is important because the SAML xsd's enforce sequence on
            // signed
            // info.)
            org.w3c.dom.Node xmlSigInsertionPoint = null;
            String JSR_105_PROVIDER = "org.jcp.xml.dsig.internal.dom.XMLDSigRI";
            String SAML_PROTOCOL_NS_URI_V20 = "urn:oasis:names:tc:SAML:2.0:protocol";
            org.w3c.dom.NodeList nodeList = w3cElement.getElementsByTagNameNS(
                    SAML_PROTOCOL_NS_URI_V20, "Extensions");
            if (nodeList.getLength() != 0) {
                xmlSigInsertionPoint = nodeList.item(nodeList.getLength() - 1);
            } else {
                nodeList = w3cElement.getElementsByTagNameNS(
                        SAML_PROTOCOL_NS_URI_V20, "Status");
                xmlSigInsertionPoint = nodeList.item(nodeList.getLength() - 1);
            }
            dsc.setNextSibling(xmlSigInsertionPoint);
            // Marshal, generate (and sign) the enveloped signature
            XMLSignature signature = sigFactory.newXMLSignature(signedInfo,
                    keyInfo);
            signature.sign(dsc);
            // Create the root dom element from the w3cElement using DOMBuilder
            DOMBuilder domBuilder = new DOMBuilder();
            org.jdom.Element signedElement = domBuilder.build(w3cElement);
            doc.setRootElement((org.jdom.Element) signedElement.detach());
            xmlOutputter = new XMLOutputter();
            strFinalResponse = xmlOutputter.outputString(doc);
            System.out.println("The signed SAML Response is : "
                    + strFinalResponse);
        } catch (Exception e) {
            System.out
                    .println("Exception while attempting to sign the SAML Response.");
            e.printStackTrace();
        }
    }

相关内容

  • 没有找到相关文章

最新更新