签名加密验证不成功opensaml

时间:2015-03-30 19:59:51

标签: java validation saml saml-2.0 opensaml

我正在尝试对使用OpenSAML从身份提供商处获得的SAML2响应进行签名验证。我试图从本地文件系统读取响应。

这是我的代码:

  DefaultBootstrap.bootstrap();
  BasicParserPool ppMgr = new BasicParserPool();
  ppMgr.setNamespaceAware(true);

 //Read file from the filesystem

 File file1=new File("F:/Softwares/Assertion.xml");
 InputStream inCommonSaml=new FileInputStream(file1);

 // Parse file
Document inCommonSamlDoc = ppMgr.parse(inCommonSaml);
Element metadataRoot = inCommonSamlDoc.getDocumentElement();
UnmarshallerFactory    unmarshallerFactory=configuration.getUnmarshallerFactory();
 Unmarshaller unmarshaller =    unmarshallerFactory.getUnmarshaller(metadataRoot);
 Response  inCommonSamlRes = (Response)  unmarshaller.unmarshall(metadataRoot);

  //Get certificate
   SignatureValidator signatureValidator = new SignatureValidator(cert);
   Signature  signature=inCommonSamlRes.getSignature();
   signatureValidator.validate(signature);


   try {
        BasicX509Credential credential = new BasicX509Credential();

        File file2=new File("F:/Softwares/publicKey.crt");
        InputStream samlCertificate=new FileInputStream(file2);         
          CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        //    
            @SuppressWarnings("deprecation")
            java.security.cert.X509Certificate certificate = (java.security.cert.X509Certificate) certificateFactory.generateCertificate(samlCertificate);
           // 

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


            credential.setPublicKey(key);
            Object obj = (credential).getPublicKey();
            if (obj instanceof RSAPublicKey) {
                BigInteger modulus = ((RSAPublicKey) obj).getModulus();
                BigInteger exponent = ((RSAPublicKey) obj).getPublicExponent();
                System.out.println("modulus");
                System.out.println (org.apache.commons.codec.binary.Base64.encodeBase64String(modulus.toByteArray()));
                System.out.println("public exponent:");
                System.out.println (org.apache.commons.codec.binary.Base64.encodeBase64String(exponent.toByteArray()));

    }
     //     System.out.println ("public key is: //n//r"+ credential.getPublicKey());
            return credential;  



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

注意:我也使用相同的证书(publicKey.crt)来签署断言 我收到以下错误: 签名加密验证不成功。

请告诉我哪里错了?错误是什么意思?它是说公钥和私钥是一样的吗?

谢谢, aswini J

2 个答案:

答案 0 :(得分:0)

我认为您需要从IdP(身份提供商)服务器获取.jks文件。此外,当您从IDP获取POST的SAMLResponse时,此SAMLResponse应包含Signature(FYI - 将是一个编码字符串,您可以使用Open SAML库进行解码和读取,可在Maven Central Repository上获得)。 获得签名后,您可以使用OpenSAML

进行验证
sigValidator.validate(response.getSignature());

如果一切正常,此方法将为您提供meesage。参考消息"签名使用提供的凭证中的密钥进行验证"

您可以点击以下链接:http://sureshatt.blogspot.in/2012/11/how-to-read-saml-20-response-with.html获取签名和

(IMP):您的IDP(身份提供商)应该发送(可能是通过HTTP POST),以便您可以从中获取NameID,即ClinetId

答案 1 :(得分:0)

此答案适用于收到此错误并在Google上搜索的传入人。

就我而言,我面临同样的错误:“错误:签名加密验证不成功”,案例略有不同。我将 SimpleSamlPHP 验证为 SP ,将 CAS 验证为 IDP

问题在于我的 SP 使用一个(自签名)证书对SPP进行验证,另一个证书用于Apache中的SP以允许SSL(这样我可以使用https)< / p>

使用两个单独的证书可能适用于许多进程,如登录和元数据验证,但是如果有注销这样的错误,就会发生上述错误。

解决方案是两个进程只使用一个证书,我的错误消失了。