2015-03-30 148 views
1

我想对使用OpenSAML的身份提供者获取的SAML2响应进行签名验证。我正试图从本地文件系统读取响应。签名加密验证不成功opensaml

这里是我的代码:

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Ĵ

+0

你可以发布assertion.xml的要点吗? – 2015-04-07 14:13:50

回答

0

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

sigValidator.validate(response.getSignature()); 

这种方法会给你meesage如果一切正常。 http://sureshatt.blogspot.in/2012/11/how-to-read-saml-20-response-with.html得到签名和

(IMP)::你的IDP(身份提供者)应该被发送(

您可以点击此链接“从供应credentia密钥来确认签名”参考消息可能会通过HTTP POST),以便您可以从中获得NameID,即ClinetId

+0

.jks?你的意思是Java密钥?如何得到它?我正在使用基于Java的工具作为身份提供者。感谢 – Ashwini 2015-04-21 10:23:46

+0

不,它由keytool创建。您正在使用哪个IDP(身份提供商)?在我的应用程序中,我使用了WSO2 IDP,它具有wso2carbon.jks文件。这个文件包含公钥和私钥...... PrivateKey与我和公钥一起使用服务器,他们是密钥对来识别每个人的身份, – Prateek 2015-04-21 10:46:37

0

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

就我而言,我面临着同样的错误:“错误:签名加密验证不成功”,稍有不同的情况。我验证了SimpleSamlPHPSPCAS as IDP

的问题是,我SP用了一个SP验证,IDP(自签名)证书,以及其他证书的SP在Apache中做出允许SSL(这样我就可以有HTTPS)

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

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