【问题标题】:OpenSAML: Include X509 Certificate in EncyptedAssertionOpenSAML:在 EncyptedAssertion 中包含 X509 证书
【发布时间】:2016-09-06 12:35:34
【问题描述】:

我正在尝试使用 OpenSAML 实现 IDP 发起的 SSO,并且 ComponentSpace 充当 SP。 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>

【问题讨论】:

  • 只是为了澄清最初的声明,ComponentSpace 不要求对 SAML 断言进行加密。我们支持纯文本和加密的 SAML 断言。加密的断言可能是作为服务提供商的组织的要求。

标签: saml-2.0 opensaml


【解决方案1】:

检查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();
        }

    }

【讨论】:

  • 感谢@Zeigeist 的输入,但签名对我有用。我在断言加密方面遇到问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-28
  • 1970-01-01
  • 1970-01-01
  • 2011-02-14
  • 1970-01-01
相关资源
最近更新 更多