2017-06-22 10 views
0

次のコードを使用して、SAMLの署名を正常に作成しています。 XMLマークを使用してPOSTをソートしましたが、REDIRECTは完全に異なります。私はhttps://www.samltool.com/sign_logout_req.phpと同じ署名を生成することができません。真正の署名を検証しようとすると失敗します。SAMLリダイレクト署名または検証で正しい署名が生成されない

私は基本に戻って同じ方法で署名できるかどうかを試してみましたが、私がデータを形成する方法に何か間違っていることを示唆することはできません。

次の詳細(samltool.comへ):

<saml:LogoutRequest ID="_02380F63816E0E92D6537758C37FE05F" Version="2.0" IssueInstant="2017-06-21T15:34:59.911Z" Destination="https://myteststs.net/appname/auth/" xmlns:saml="urn:oasis:names:tc:SAML:2.0:protocol"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://w.sp-app.com</saml:Issuer><saml:NameID xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">1869374313</saml:NameID></saml:LogoutRequest> 

プライベートキー(testcert)

MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAL13oqZ+pNa/fYIc+GYBrENOQ9rKWMeQEL9iDJyj7DFrQA40jOCY1UiOT2uLYvIwfqTHMuPmmlOLSyqCumZbKYP6KIM0pe+vJcJO6Nxg81gmN3jx3GbnDsmhi54oAmj3JC/Z/WbliqUXjlIAUlzLmMll7/vy2V5ec/gxHBpuRWBjAgMBAAECgYAWiWn/+vV5k9qGhRKo8479jIw2tLX9uu27Dhso8LiyIitC5U5Skutfz4mz5acV3t3ZlNZBVJdL07hTrKwma7aSx1r6UwTtW002ZZzytEVn7G7ytOIXkT+q/TuooCR8aa88vwhUFPqCSOuZgOPH9ytqAkzDCaNgVKdhQgRgjxfOBQJBAOSu4t5AgFJUBOcYOEOm6+v8R1CqedfyOgya3g1gsA4VnuG+ms233ZxWSPkiMnoUpEh8gBnZyk6ZZSlk668rwBcCQQDUGYg7wVLqhPAyjfM74oaJgohyQfQK6rPnzlKoGbdDR0QRN545ATBsETi2GSIYAHgkgLDJw3/lw1wX1dXzFuWVAkABmR9IwlajPKcUHl02S9JWQdsVuztCwRSaxfJLUaOpVYlYtoZKbcCEuS2lYBHOPJqxTv1uMNFzHytP0L686KddAkART6gr4GKJG6KTLbzNhXafoJTMZo+pmHBomhFrAPZROm7WzOhQFMXD/D/ZtQFwXhFwQUSsoxU8Ro6sr1pQBe1lAkBlXndo3Bm6AITDDsJZYg10XiBMNj4743t0pV6jayf9UTRZHu2GI9AWoU3/FTQt34zbPz6TjlNuJnwMHwfCFk1F 

X.509

MIICMTCCAZqgAwIBAgIQcuFBQn5d27JBvbkCO+utKjANBgkqhkiG9w0BAQUFADBXMVUwUwYDVQQDHkwAewAyAEYAOAA3ADkANQA4ADUALQA3AEMANQA0AC0ANAA1ADAARAAtADgAOABGAEIALQBBADMARgA3ADEAMwA2ADQANgBFAEMANgB9MB4XDTE2MDEwODExMTU0OFoXDTE3MDEwNzE3MTU0OFowVzFVMFMGA1UEAx5MAHsAMgBGADgANwA5ADUAOAA1AC0ANwBDADUANAAtADQANQAwAEQALQA4ADgARgBCAC0AQQAzAEYANwAxADMANgA0ADYARQBDADYAfTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvXeipn6k1r99ghz4ZgGsQ05D2spYx5AQv2IMnKPsMWtADjSM4JjVSI5Pa4ti8jB+pMcy4+aaU4tLKoK6Zlspg/oogzSl768lwk7o3GDzWCY3ePHcZucOyaGLnigCaPckL9n9ZuWKpReOUgBSXMuYyWXv+/LZXl5z+DEcGm5FYGMCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBDXaccjXBrBhxp1fcEDm7MotKvgh8DxQAACk/Uxb4r2R6+LcePUxQTcxWVmyCQO0NR017FRf/fLFHmM9HZI3lwx5ka4xBnSOu8mejQ0KOYt4yf2VQG6pWGa046Ntip+KB/yDQKXQ3RHprsshe33MFlEWpDJyo6jyDpDUqLjPBvtg== 

リレー状態:

RELAYTEST 
コードを使用して

IG4VDmVwQRZWa75NmwjtqKlPVdCx6tm73gL7j3xvrqXsfirunUtr626SBmQJ4mke77bYzXg8D1hAy5EREOhz2QH23j47XexqbVSNTtAkZV7KP1/lO8K01tiQr8SGJqzdFor/FZZscIDFlw3cBLXhGSwWK9i0qO/e55qkgxJS9OA =

しかし..:210

SigAlg:それは署名を生成ssotoolを使用して

#rsa-sha1 

だから... ...下の(そして多くの..多くのバリエーション)同じシグネチャを生成することはできません。 samlrequestは、推奨されているようにbase64エンコードされていることに注意してください(ただし、同じ出力に収縮させることができます)。私も(3.4.4.1)この仕様に従っている:https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf

static byte[] Sign(string data, string certSubject) 
    { 

     // Access Personal (MY) certificate store of current user 
     X509Store my = new X509Store(StoreName.My, StoreLocation.LocalMachine); 
     my.Open(OpenFlags.ReadOnly); 


     // Find the certificate we’ll use to sign 
     RSACryptoServiceProvider csp = null; 

     foreach (X509Certificate2 cert in my.Certificates) 
     { 
      if (cert.Subject.Contains(certSubject)) 
      { 
       // Get its associated CSP and private key 
       csp = (RSACryptoServiceProvider)cert.PrivateKey; 

      } 
     } 

     if (csp == null) 
     { 
      throw new Exception("No valid cert was found"); 
     } 

     string certAlgorithm = csp.SignatureAlgorithm; 


     // Hash the data 
     SHA1Managed sha1 = new SHA1Managed(); 
     UnicodeEncoding encoding = new UnicodeEncoding(); 

     byte[] dataRaw = encoding.GetBytes(data); 
     byte[] hash = sha1.ComputeHash(dataRaw); 


     // Sign the hash 
     return csp.SignHash(hash, CryptoConfig.MapNameToOID("SHA1")); 
    } 

    static bool Verify(string text, byte[] signature, string certPublic) 
    { 

     // Load the certificate we’ll use to verify the signature from a file 
     X509Certificate2 appSigningX509Certificate = null; 
     var appSigningCertificateBytes = Convert.FromBase64String(certPublic); 
     appSigningX509Certificate = new X509Certificate2(appSigningCertificateBytes); 

     // Get its associated CSP and public key 
     RSACryptoServiceProvider csp = (RSACryptoServiceProvider)appSigningX509Certificate.PublicKey.Key; 


     // Hash the data 
     SHA1Managed sha1 = new SHA1Managed(); 
     UnicodeEncoding encoding = new UnicodeEncoding(); 

     byte[] data = encoding.GetBytes(text); 
     byte[] hash = sha1.ComputeHash(data); 


     // Verify the signature with the hash 
     return csp.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), signature); 
    } 


    static void Main(string[] args) 
    { 

     // Usage sample 
     try 
     { 

      string cert = "MIICMTCCAZqgAwIBAgIQcuFBQn5d27JBvbkCO+utKjANBgkqhkiG9w0BAQUFADBXMVUwUwYDVQQDHkwAewAyAEYAOAA3ADkANQA4ADUALQA3AEMANQA0AC0ANAA1ADAARAAtADgAOABGAEIALQBBADMARgA3ADEAMwA2ADQANgBFAEMANgB9MB4XDTE2MDEwODExMTU0OFoXDTE3MDEwNzE3MTU0OFowVzFVMFMGA1UEAx5MAHsAMgBGADgANwA5ADUAOAA1AC0ANwBDADUANAAtADQANQAwAEQALQA4ADgARgBCAC0AQQAzAEYANwAxADMANgA0ADYARQBDADYAfTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvXeipn6k1r99ghz4ZgGsQ05D2spYx5AQv2IMnKPsMWtADjSM4JjVSI5Pa4ti8jB+pMcy4+aaU4tLKoK6Zlspg/oogzSl768lwk7o3GDzWCY3ePHcZucOyaGLnigCaPckL9n9ZuWKpReOUgBSXMuYyWXv+/LZXl5z+DEcGm5FYGMCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBDXaccjXBrBhxp1fcEDm7MotKvgh8DxQAACk/Uxb4r2R6+LcePUxQTcxWVmyCQO0NR017FRf/fLFHmM9HZI3lwx5ka4xBnSOu8mejQ0KOYt4yf2VQG6pWGa046Ntip+KB/yDQKXQ3RHprsshe33MFlEWpDJyo6jyDpDUqLjPBvtg=="; 

      string samlRequestCompressed = "nZFPS8QwEMW/Ssl906TZ/gttQWwLhdWDyh68SKjBLbRJ7ExQv71traA38TiPee/9hilATaM82Rfr8U6/eg0YdHVJnlgkMtYmIuNJw5o8qpNYpGmcXYu0bVjckuCsZxisKUlEGQk6AK87A6gMLhLj6YElh4g/8FiKo4xzmnP+SIJ6aRiMws15QXQgwxC1Uab/MGrSdFBTP1r/TI3GUDm3iqE7KI+XkATv02hArtAl8bORVsEAct0Bib28v7o5yYVHutmi7e1IqmK7cMOb/2xXAHpeGUn1zfhGYaFwjvZ2KsIfoXvD7RLS1f9p4FmSi/QouNhzv6Kqffr1nOoT"; 
      string relaystate = "RELAYTEST"; 
      string algorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; 

      string data = String.Empty; 
      if (String.IsNullOrEmpty(relaystate)) 
      { 
       data = String.Format("SAMLRequest={0}&SigAlg={1}", HttpUtility.UrlEncode(samlRequestCompressed), HttpUtility.UrlEncode(algorithm)); 
      } 
      else 
      { 
       data = String.Format("SAMLRequest={0}&RelayState={1}&SigAlg={2}", HttpUtility.UrlEncode(samlRequestCompressed,Encoding.UTF8), HttpUtility.UrlEncode(relaystate,Encoding.UTF8), HttpUtility.UrlEncode(algorithm,Encoding.UTF8)); 
      } 

      // Sign text 
      byte[] signature = Sign(data, "{2F879585-7C54-450D-88FB-A3F713646EC6}"); 

      string b64encodedSig = Convert.ToBase64String(signature); 
      string expectedSig = "IG4VDmVwQRZWa75NmwjtqKlPVdCx6tm73gL7j3xvrqXsfirunUtr626SBmQJ4mke77bYzXg8D1hAy5EREOhz2QH23j47XexqbVSNTtAkZV7KP1/lO8K01tiQr8SGJqzdFor/FZZscIDFlw3cBLXhGSwWK9i0qO/e55qkgxJS9OA="; 

      if (b64encodedSig != expectedSig) 
      { 
       Console.WriteLine("Not what i expected"); 
       Environment.Exit(0); 
      } 

      // Verify signature. Testcert.cer corresponds to “cn=my cert subject” 
      if (Verify(data, signature, cert)) 
      { 
       Console.WriteLine("Signature verified"); 
      } 
      else 
      { 
       Console.WriteLine("ERROR: Signature not valid!"); 
      } 
     } 

     catch (Exception ex) 
     { 
      Console.WriteLine("EXCEPTION: " +ex.Message); 
     } 

     Console.ReadKey(); 
    } 

私は同じように符号データを生成する方法を理解するように見えることはできません。また、ローカルにインストールされた証明書が上記のものとまったく同じであることを確認しました。

答えて

0

私はこれを今解決しました。

解決策は、HttpUtility.URLEncodeがSAML標準(またはOneLogin)と同じ標準にエンコードしていないことでした。私は、圧縮されたデータを見て、それが合っているが、URLエンコードされたものを見て、それを理解しました。

答えはUri.EscapeStringを使用することでした。

関連する問題