2016-03-22 5 views
1

У нас недавно возникла проблема, когда IdP не доверял подпискам на запрос выхода SAML 2.0 из нашего RP/SP. Мы искали альтернативные способы проверки подписи запроса SAML, так как IdP и samltool.com жаловались на проверку подписи. Ниже приведен пример ответа, который мы использовали для проверки подписанных данных, которые могут быть проверены против подписи.PowerShell Validate SAML Signed XML

+0

Этот код не может правильно проверить подпись и уязвим для атак XML-подписи, поскольку он не проверяет ссылки. Я написал [сообщение в блоге] (https://coding.abel.nu/2015/12/xml-signatures-and-references/) о том, какие ссылки и почему их проверка является обязательной. –

+0

@AndersAbel, я не уверен, что следую вашему комментарию 100%. В моих тестах этого кода, когда я изменяю подписанные данные, проверка подписи XML затем возвращает false, как ожидалось. Если вы говорите о проверке доверия всего XML-документа, то это выходит за рамки того, что я пытался показать. Это простой скрипт, который проверяет подпись подписанных данных. В обоих примерах я предоставляю ключевую информацию в $ подписанном объекте, указываете ли вы, что мне все равно нужно предоставить его в качестве аргумента в $ 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") 

Validate 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() 

Modify XML так подпись не может быть подтверждено в приведенном выше примере:

$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() 

Validate SAML 2.0 HTTP-POST запрос с сертификатом, включенным в запросе:

$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, я обновил формат вопроса/ответа. –