2015-03-30 147 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)

使用兩個單獨的證書可能適用於很多過程,例如登錄和元數據驗證,但是像註銷這樣的過程會發生上述錯誤。

解決方案是隻爲這兩個進程使用一個證書,並且我的錯誤消失了。