XML signature verification in Powershell with PEM certificate

I am trying to create a powershell script that will consume data in an XML document. However, before doing any work, I need to verify that the XML has not been tampered with by validating the signature.

I have a copy of the public key for the certificate used for XML signing in PEM format, but I cannot figure out how to get powershell to use that certificate.

The closure I came with to get this to work is the following code ...

$Path = "data.xml"
$Xmldata = new-object Xml.XmlDocument
$Xmldata.PreserveWhitespace = $true
$Xmldata.Load($Path)

add-type -AssemblyName system.security
$SignedXml = New-Object System.Security.Cryptography.Xml.SignedXml -ArgumentList $Xmldata

$XmlNodeList = $Xmldata.EntitiesDescriptor.Signature

$XmlNodeList

$SignedXml.LoadXml($XmlNodeList)

$CertPath = "cert.pem"
$Check = $SignedXml.CheckSignature($CertPath, $true)

      

However, when this is executed, I get the following exception ...

Throwing "CheckSignature" exception with argument "2": "SignatureDescription could not be generated to sign the provided algorithm." By line: 34 char: 1 + $ Check = $ SignedXml.CheckSignature ($ CertPath, $ true) + ~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ ~~~ + CategoryInfo: NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId: CryptographicException

Any help would be greatly appreciated. Thank!

+3


source to share


1 answer


After some intensive additional searching, I found that SignedXML does not support the http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 algorithm , which had to be added manually. I had to add the following code before creating signedXML object ...

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")

      



This solution was adapted from a C # example of the same problem as at http://geekswithblogs.net/mkoerner/archive/2013/07/12/saml2-federationmetadata-validation.aspx .

+1


source







All Articles