2016-03-22 25 views
1

最近、IdPがRP/SPのSAML 2.0ログアウトリクエストの署名を信頼していないという問題がありました。私たちは、IdPとsamltool.comの両方が署名の検証について不満を持っていたため、SAML要求の署名を検証する代替方法を模索していました。署名されたデータを検証するために使用した回答の例を以下に示します。PowerShell SAML署名付きXMLの検証

+0

このコードは署名を正しく検証することができず、参照をチェックしないため、XML署名ラッピング攻撃に対して脆弱です。私は[ブログ記事](https://coding.abel.nu/2015/12/xml-signatures-and-references/)に何が参照されているのか、なぜそれらをチェックする必要があるのか​​を書きました。 –

+0

@AndersAbel、私はあなたのコメントに100%従うのか分からない。このコードのテストでは、署名付きデータを変更すると、XML署名の検証が期待通りにfalseを返します。 XML文書全体の信頼性を検証することについて話しているのであれば、それは私が示しているものの範囲を超えています。これは、署名されたデータの署名を検証する単純なスクリプトです。 どちらの例でも、$ signedオブジェクトにキー情報を提供していますが、$ signed.CheckSignature()の引数として指定する必要があることを示していますか? –

+0

@AndersAbel私は今理解していると思うが、このコードはSAMLトークンの信頼性/妥当性をチェックするためのものではなく、署名されたデータに基づいて署名パスを検証するだけである。 –

答えて

2

追加必要なタイプと定義SHA256

Add-Type -AssemblyName System.Security 

# Add SHA-256 per http://stackoverflow.com/questions/30759119/verifying-xml-signature-in-powershell-with-pem-certificate 
Add-Type @' 
     public class RSAPKCS1SHA256SignatureDescription : System.Security.Cryptography.SignatureDescription 
      { 
       public RSAPKCS1SHA256SignatureDescription() 
       { 
        base.KeyAlgorithm = "System.Security.Cryptography.RSACryptoServiceProvider"; 
        base.DigestAlgorithm = "System.Security.Cryptography.SHA256Managed"; 
        base.FormatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureFormatter"; 
        base.DeformatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureDeformatter"; 
       } 

       public override System.Security.Cryptography.AsymmetricSignatureDeformatter CreateDeformatter(System.Security.Cryptography.AsymmetricAlgorithm key) 
       { 
        System.Security.Cryptography.AsymmetricSignatureDeformatter asymmetricSignatureDeformatter = (System.Security.Cryptography.AsymmetricSignatureDeformatter) 
         System.Security.Cryptography.CryptoConfig.CreateFromName(base.DeformatterAlgorithm); 
        asymmetricSignatureDeformatter.SetKey(key); 
        asymmetricSignatureDeformatter.SetHashAlgorithm("SHA256"); 
        return asymmetricSignatureDeformatter; 
       } 
      } 
'@ 
$RSAPKCS1SHA256SignatureDescription = New-Object RSAPKCS1SHA256SignatureDescription 
[System.Security.Cryptography.CryptoConfig]::AddAlgorithm($RSAPKCS1SHA256SignatureDescription.GetType(), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256") 

ため検証SAML証明書なしで2.0 HTTP-POSTリクエストは、リクエストに含まれる:

$saml = "insert real saml request here" 

$decoded = [System.Convert]::FromBase64String($saml) 
$stream = [System.IO.MemoryStream]::new($decoded, 0, $decoded.length) 

$xml = New-Object System.Xml.XmlDocument 
$xml.PreserveWhitespace = $true 
$xml.Load($stream) 

$signed = New-Object System.Security.Cryptography.Xml.SignedXml -ArgumentList $xml 
$signed.LoadXml($xml.DocumentElement.Assertion.Signature) 

$cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new("C:\Users\username\Desktop\idp.cer") 

$keyinfo = [System.Security.Cryptography.Xml.KeyInfo]::new() 
$clause = [System.Security.Cryptography.Xml.KeyInfoX509Data]::new($cert) 
$keyinfo.AddClause($clause) 

$signed.KeyInfo = $keyinfo 

$signed.CheckSignature() 

変更XML署名を検証することができないので上記の例では:

検証SAML証明書を使用して2.0 HTTP-POSTリクエストは、リクエストに含ま
$xml.Response.Assertion.Subject.NameID.'#text' = 'asdasdasd' 

$signed = New-Object System.Security.Cryptography.Xml.SignedXml -ArgumentList $xml 
$signed.LoadXml($xml.DocumentElement.Assertion.Signature) 

$cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new("C:\Users\username\Desktop\idp.cer") 

$keyinfo = [System.Security.Cryptography.Xml.KeyInfo]::new() 
$clause = [System.Security.Cryptography.Xml.KeyInfoX509Data]::new($cert) 
$keyinfo.AddClause($clause) 

$signed.KeyInfo = $keyinfo 

$signed.CheckSignature() 

$saml = "insert example saml request here" 
$decoded = [System.Convert]::FromBase64String($saml) 
$stream = [System.IO.MemoryStream]::new($decoded, 0, $decoded.length) 

$xml = New-Object System.Xml.XmlDocument 
$xml.PreserveWhitespace = $true 
$xml.Load($stream) 

$signed = New-Object System.Security.Cryptography.Xml.SignedXml -ArgumentList $xml 
$signed.LoadXml($xml.DocumentElement.Signature) 
$signed.CheckSignature() 

変更XML署名ので、上記の例では検証できない。

$xml.LogoutRequest.NameID.'#text' = "dasdasd" 

$signed = New-Object System.Security.Cryptography.Xml.SignedXml -ArgumentList $xml 
$signed.LoadXml($xml.DocumentElement.Signature) 


# Should return false since we modified the data 
$signed.CheckSignature() 

うまくいけば、この節約同じタスクを達成する必要がある場合は、他の誰かにしばらくお待ちください。ご意見やご提案があれば教えてください。

ありがとうございます!

+0

良い提案@AndersAbel、質問/回答の形式を更新しました。 –

関連する問題