OpenSAML(2.0)签名验证无效

时间:2013-07-26 20:39:15

标签: saml-2.0 xml-signature opensaml

问题:

我正在使用OpenSAML构建一种方法来验证发布到我们服务器的SAML 2.0响应。我有大部分工作,能够访问断言的各个方面。唯一的问题是,当我尝试使用下面的公钥验证签名时,它指出“签名未验证凭据的密钥”。

有什么想法吗?

公钥:

MIICozCCAgygAwIBAgIGATxK1oY4MA0GCSqGSIb3DQEBBQUAMIGUMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
MBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDHdlc3Rlcm51bmlvbjEcMBoGCSqGSIb3DQEJ
ARYNaW5mb0Bva3RhLmNvbTAeFw0xMzAxMTcyMzI2MThaFw00MzAxMTcyMzI3MThaMIGUMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsG
A1UECgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDHdlc3Rlcm51bmlvbjEc
MBoGCSqGSIb3DQEJARYNaW5mb0Bva3RhLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
njQZkKTyJuS1evlG/ThBqGT9VID9RnN31yr1EQXYODs1pXy8w58QkztCWTvevj8GekbJ8dsVZ2Ij
UXJ50psNL1zyq0cJp8M08E75SCwaH7Q9goaReIFpYQZTbTE9FMfGcsrNIFZyBsCXS2dm+FfuGDQ6
4/W0mxOHdYxqSTD+fvMCAwEAATANBgkqhkiG9w0BAQUFAAOBgQByeciVKaK5IKFPVzK3ZS37IOQm
2vDXZYXEzUaq1urk8gunQs75ZzgIsIh6jlUZy+FO3maAoVyW5mUzqT0jBTfI0Ea3vJfQAlgn4gW2
eiqdbu1uI48a5K1+GneO1xzqTYzMXvUoJpXqoifsrikkpHHATF8z5Y4ULKgKFSBB9VypDg==

签名:

<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="#id7437579890833705637451361">
            <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>zIoW9N/wJrjwXfQS7I5jNyZqbJQ=</ds:DigestValue>
        </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>ZybzDLQ2Q8RiIqyShZFNKR8+vbVhjsAT18hIh6IcqDO5ER2ah5Fs1bErmgeITatRNgdqzxgX4jErtkituiI3vdr56g5kmaTKHf2lrU6OLW3JHUokCt9Bv9E7duvnpGEA0uFvzNMVMcqZOGUbJ1m1lkYxUIIaeOjSxPjBTZB+g3A=</ds:SignatureValue>
    <ds:KeyInfo>
        <ds:X509Data>
            <ds:X509Certificate>MIICozCCAgygAwIBAgIGATxK1oY4MA0GCSqGSIb3DQEBBQUAMIGUMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
MBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDHdlc3Rlcm51bmlvbjEcMBoGCSqGSIb3DQEJ
ARYNaW5mb0Bva3RhLmNvbTAeFw0xMzAxMTcyMzI2MThaFw00MzAxMTcyMzI3MThaMIGUMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsG
A1UECgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDHdlc3Rlcm51bmlvbjEc
MBoGCSqGSIb3DQEJARYNaW5mb0Bva3RhLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
njQZkKTyJuS1evlG/ThBqGT9VID9RnN31yr1EQXYODs1pXy8w58QkztCWTvevj8GekbJ8dsVZ2Ij
UXJ50psNL1zyq0cJp8M08E75SCwaH7Q9goaReIFpYQZTbTE9FMfGcsrNIFZyBsCXS2dm+FfuGDQ6
4/W0mxOHdYxqSTD+fvMCAwEAATANBgkqhkiG9w0BAQUFAAOBgQByeciVKaK5IKFPVzK3ZS37IOQm
2vDXZYXEzUaq1urk8gunQs75ZzgIsIh6jlUZy+FO3maAoVyW5mUzqT0jBTfI0Ea3vJfQAlgn4gW2
eiqdbu1uI48a5K1+GneO1xzqTYzMXvUoJpXqoifsrikkpHHATF8z5Y4ULKgKFSBB9VypDg==</ds:X509Certificate>
        </ds:X509Data>
    </ds:KeyInfo>
</ds:Signature>

实施

try {
    //Retrieve SAML response from post
    Document document = ppMgr.parse(request.getInputStream());
    UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
    Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(document.getDocumentElement());
    response = (Response)unmarshaller.unmarshall(document.getDocumentElement());

    //Get Public Key
    BasicX509Credential publicCredential = new BasicX509Credential();
    File publicKeyFile = new File("C:/saml.cer");

    if (publicKeyFile.exists()) {
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        InputStream fileStream = new FileInputStream(publicKeyFile);
        X509Certificate certificate = (X509Certificate)certificateFactory.generateCertificate(fileStream);
        fileStream.close();

        X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(certificate.getPublicKey().getEncoded());
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        key = keyFactory.generatePublic(publicKeySpec);

        //Validate Public Key against Signature
        if (key != null) {
            publicCredential.setPublicKey(key);
            SignatureValidator signatureValidator = new SignatureValidator(publicCredential);
            signatureValidator.validate(signature);
        }
    }

    returnValue = true;
} catch (ValidationException e) {
    throw e; //Throws a 'Signature did not validate against the credential's key' exception
}

1 个答案:

答案 0 :(得分:7)

嗯,事实证明上面的代码 是正确的。这是样本SAML响应不正确。我想从这一切中汲取的教训就是相信你的实施:)