签名未验证凭据的密钥

时间:2018-03-30 20:06:12

标签: java xml security saml opensaml

我有来自idp的saml响应,它在响应和断言中都被签名。我正在尝试使用X509证书验证签名是否为公钥。这是我的代码

public class SamlTest {

public static void main(String[] args) throws Exception {

    // read the file
    File file = new File("filepath");   
    FileReader fileReader = new FileReader(file);
    BufferedReader bf = new BufferedReader(fileReader);
    String str;
    String samlStr = "";
    while ((str = bf.readLine()) != null) {
        samlStr += str;
    }

    Response response = SamlTest.unmarshall(samlStr);

    SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator();
    try {
        profileValidator.validate(response.getSignature());
    } catch (ValidationException e) {
        System.out.println("ErrorString [Error in SAMLSignatureProfilValidation]");
    }

    Certificate certificate = SamlTest.getCertificate(response.getSignature());

    BasicCredential verificationCredential = new BasicCredential();
    verificationCredential.setPublicKey(certificate.getPublicKey());


    SignatureValidator sigValidator = new SignatureValidator(verificationCredential);
    try {
        sigValidator.validate(response.getSignature());
    } catch (ValidationException e) {
        e.printStackTrace();
    }
}

private static Response unmarshall(String samlStr) throws Exception {

    DefaultBootstrap.bootstrap();
    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
    documentBuilderFactory.setNamespaceAware(true);
    DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();

    ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(samlStr.getBytes());

    Document document = docBuilder.parse(byteArrayInputStream);

    Element element = document.getDocumentElement();
    UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
    Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(element);

}

private static Certificate getCertificate(Signature signature) {
    try {
        X509Certificate certificate = signature.getKeyInfo().getX509Datas().get(0).getX509Certificates().get(0);

        if (certificate != null) {
            //Converts org.opensaml.xml.signature.X509Certificate to java.security.cert.Certificate
            String lexicalXSDBase64Binary = certificate.getValue();
            byte[] decoded = DatatypeConverter.parseBase64Binary(lexicalXSDBase64Binary);

            try {
                CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
                Certificate cert = certFactory.generateCertificate(new ByteArrayInputStream(decoded));
                System.out.println(cert);
                return cert;
            } catch (CertificateException e) {
                //this should never happen
                System.out.println("SAML Signature issue");
                return null;
            }
        }
        return null; // TODO Auto-generated method stub

    } catch (NullPointerException e) {
        //Null certificates

        return null;
    }
}}

我尝试了多个saml响应,而不仅仅是我的。但我得到一个错误说:

WARN org.apache.xml.security.signature.XMLSignature - 签名验证失败。 org.opensaml.xml.validation.ValidationException:签名未针对凭证密钥进行验证

之前已经提出过这个问题但是从来没有一个明确的答案,所以再问一遍。

我想测试的saml响应示例如下:

<?xml version="1.0"?>
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
            ID="pfx7832688a-4c9f-d986-a331-68a568701125" Version="2.0" IssueInstant="2014-07-17T01:01:48Z"
            Destination="http://sp.example.com/demo1/index.php?acs"
            InResponseTo="ONELOGIN_4fee3b046395c4e751011e97f8900b5273d56685">
<saml:Issuer>http://idp.example.com/metadata.php</saml:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
        <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
        <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
        <ds:Reference URI="#pfx7832688a-4c9f-d986-a331-68a568701125">
            <ds:Transforms>
                <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <ds:DigestValue>omD68BGTOD4rSkKgo3zHEz2D0Ak=</ds:DigestValue>
        </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>
        C+QerLk231g7kSvB/Bo+JrfdYHrzqt+3ql0+WqBIOPRx7xHHvvSx1GiUyDncs7x+LnldDHb/jU8V1Bay+mHKaKB2GnL06XZW33vK/z5GsVLzIF7h9mfybRrbFwdOPYNQzHgnGxWDp3LsehzL58cRXtu2V+aLbYRB0e3wI6tcpBY=
    </ds:SignatureValue>
    <ds:KeyInfo>
        <ds:X509Data>
            <ds:X509Certificate>
                MIICajCCAdOgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBSMQswCQYDVQQGEwJ1czETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMT25lbG9naW4gSW5jMRcwFQYDVQQDDA5zcC5leGFtcGxlLmNvbTAeFw0xNDA3MTcxNDEyNTZaFw0xNTA3MTcxNDEyNTZaMFIxCzAJBgNVBAYTAnVzMRMwEQYDVQQIDApDYWxpZm9ybmlhMRUwEwYDVQQKDAxPbmVsb2dpbiBJbmMxFzAVBgNVBAMMDnNwLmV4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZx+ON4IUoIWxgukTb1tOiX3bMYzYQiwWPUNMp+Fq82xoNogso2bykZG0yiJm5o8zv/sd6pGouayMgkx/2FSOdc36T0jGbCHuRSbtia0PEzNIRtmViMrt3AeoWBidRXmZsxCNLwgIV6dn2WpuE5Az0bHgpZnQxTKFek0BMKU/d8wIDAQABo1AwTjAdBgNVHQ4EFgQUGHxYqZYyX7cTxKVODVgZwSTdCnwwHwYDVR0jBBgwFoAUGHxYqZYyX7cTxKVODVgZwSTdCnwwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQ0FAAOBgQByFOl+hMFICbd3DJfnp2Rgd/dqttsZG/tyhILWvErbio/DEe98mXpowhTkC04ENprOyXi7ZbUqiicF89uAGyt1oqgTUCD1VsLahqIcmrzgumNyTwLGWo17WDAa1/usDhetWAMhgzF/Cnf5ek0nK00m0YZGyc4LzgD0CROMASTWNg==
            </ds:X509Certificate>
        </ds:X509Data>
    </ds:KeyInfo>
</ds:Signature>
<samlp:Status>
    <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema"
                ID="pfxbab80599-f888-0071-7fd5-1771ae32f2b5" Version="2.0" IssueInstant="2014-07-17T01:01:48Z">
    <saml:Issuer>http://idp.example.com/metadata.php</saml:Issuer>
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:SignedInfo>
            <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
            <ds:Reference URI="#pfxbab80599-f888-0071-7fd5-1771ae32f2b5">
                <ds:Transforms>
                    <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                    <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                </ds:Transforms>
                <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                <ds:DigestValue>ui6giJBmDP2ShSBq06MQ/hVkK6U=</ds:DigestValue>
            </ds:Reference>
        </ds:SignedInfo>
        <ds:SignatureValue>
            eG/U9aPs3WJjgLQwPJF+liaPVAngVXkonmLxVEmTRa01sivZboNZr+5xgNMqqXjOHsuMfpA9sCJi/Iv3u4g2YEyamo3DxdPG2h/Qx9lcA3hjKIhkKIicqCbwZhMsKupZs71FmvJCKS/MrzNiZJWxtjtCD+Rn3CpWhXPCz4vzfj8=
        </ds:SignatureValue>
        <ds:KeyInfo>
            <ds:X509Data>
                <ds:X509Certificate>
                    MIICajCCAdOgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBSMQswCQYDVQQGEwJ1czETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMT25lbG9naW4gSW5jMRcwFQYDVQQDDA5zcC5leGFtcGxlLmNvbTAeFw0xNDA3MTcxNDEyNTZaFw0xNTA3MTcxNDEyNTZaMFIxCzAJBgNVBAYTAnVzMRMwEQYDVQQIDApDYWxpZm9ybmlhMRUwEwYDVQQKDAxPbmVsb2dpbiBJbmMxFzAVBgNVBAMMDnNwLmV4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZx+ON4IUoIWxgukTb1tOiX3bMYzYQiwWPUNMp+Fq82xoNogso2bykZG0yiJm5o8zv/sd6pGouayMgkx/2FSOdc36T0jGbCHuRSbtia0PEzNIRtmViMrt3AeoWBidRXmZsxCNLwgIV6dn2WpuE5Az0bHgpZnQxTKFek0BMKU/d8wIDAQABo1AwTjAdBgNVHQ4EFgQUGHxYqZYyX7cTxKVODVgZwSTdCnwwHwYDVR0jBBgwFoAUGHxYqZYyX7cTxKVODVgZwSTdCnwwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQ0FAAOBgQByFOl+hMFICbd3DJfnp2Rgd/dqttsZG/tyhILWvErbio/DEe98mXpowhTkC04ENprOyXi7ZbUqiicF89uAGyt1oqgTUCD1VsLahqIcmrzgumNyTwLGWo17WDAa1/usDhetWAMhgzF/Cnf5ek0nK00m0YZGyc4LzgD0CROMASTWNg==
                </ds:X509Certificate>
            </ds:X509Data>
        </ds:KeyInfo>
    </ds:Signature>
    <saml:Subject>
        <saml:NameID SPNameQualifier="http://sp.example.com/demo1/metadata.php"
                     Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">
            _ce3d2948b4cf20146dee0a0b3dd6f69b6cf86f62d7
        </saml:NameID>
        <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
            <saml:SubjectConfirmationData NotOnOrAfter="2024-01-18T06:21:48Z"
                                          Recipient="http://sp.example.com/demo1/index.php?acs"
                                          InResponseTo="ONELOGIN_4fee3b046395c4e751011e97f8900b5273d56685"/>
        </saml:SubjectConfirmation>
    </saml:Subject>
    <saml:Conditions NotBefore="2014-07-17T01:01:18Z" NotOnOrAfter="2024-01-18T06:21:48Z">
        <saml:AudienceRestriction>
            <saml:Audience>http://sp.example.com/demo1/metadata.php</saml:Audience>
        </saml:AudienceRestriction>
    </saml:Conditions>
    <saml:AuthnStatement AuthnInstant="2014-07-17T01:01:48Z" SessionNotOnOrAfter="2024-07-17T09:01:48Z"
                         SessionIndex="_be9967abd904ddcae3c0eb4189adbe3f71e327cf93">
        <saml:AuthnContext>
            <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
        </saml:AuthnContext>
    </saml:AuthnStatement>
    <saml:AttributeStatement>
        <saml:Attribute Name="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
            <saml:AttributeValue xsi:type="xs:string">test</saml:AttributeValue>
        </saml:Attribute>
        <saml:Attribute Name="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
            <saml:AttributeValue xsi:type="xs:string">test@example.com</saml:AttributeValue>
        </saml:Attribute>
        <saml:Attribute Name="eduPersonAffiliation" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
            <saml:AttributeValue xsi:type="xs:string">users</saml:AttributeValue>
            <saml:AttributeValue xsi:type="xs:string">examplerole1</saml:AttributeValue>
        </saml:Attribute>
    </saml:AttributeStatement>
</saml:Assertion>

如果有人能发现问题,请告诉我。非常感谢!

1 个答案:

答案 0 :(得分:2)

当我在SAML tool上验证此消息时,我得到“签名验证失败。参考验证失败。 (强调我的)

这使我认为您可能在验证签名之前格式化或更改了xml内容。

XML签名包含两部分:签名引用转换为摘要值,然后将摘要值加密为签名值。

验证也包括以下两部分:

  1. 参考验证:通过检索相应的资源并应用任何变换然后应用指定的摘要方法来验证每个参考的摘要。将结果与记录的DigestValue进行比较;如果它们不匹配,则验证失败。
  2. 签名验证:使用CanonicalizationMethod中指定的规范化方法对SignedInfo元素进行序列化,使用KeyInfo或其他方法检索密钥数据,并使用SignatureMethod中指定的方法验证签名。