PyXMLSec: Signature ノードがどこにあってもドキュメントのデジタルシグネチャーは同じ

あたりまえだともいますが確認。python xmlsecはEnveloped Signature。

署名ルーチン

def _sign_xml(self,private_key,certificate,src_xml,at_child=False):
    ”’
    Sign a XML
    ”’

    # XML document object from a given string
    doc = libxml2.parseDoc(src_xml.encode(‘UTF-8’))

    # create a signature node(Encrpyted Signature mode) : <Signature>
    signNode = xmlsec.TmplSignature(doc, xmlsec.transformExclC14NId(),
                                xmlsec.transformRsaSha1Id(), None)

    signing_node = doc.getRootElement().firstElementChild()  if at_child else doc.getRootElement()
    signing_node.addChild(signNode)

    # create a reference : <Reference>
    refNode = signNode.addReference(xmlsec.transformSha1Id(),
                                None, None, None)
    refNode.addTransform(xmlsec.transformEnvelopedId())

    # X.509 node <KeyInfo>
    keyInfoNode = signNode.ensureKeyInfo(None)
    keyInfoNode.addX509Data()

    # Load a private key
    key = self._load_private_key(private_key)

    # Key and the Certificate loading
    xmlsec.cryptoAppKeyCertLoad(key, certificate, xmlsec.KeyDataFormatPem)

    # Sign the XML : <SignatureValue> and others…
    dsig_ctx = xmlsec.DSigCtx()
    dsig_ctx.signKey = key
    dsig_ctx.sign(signNode)
    dsig_ctx.destroy()

    return doc

プライベートキーのPEMのロード

def _load_private_key(self,pri_key_file):
    ”’
    Load a private key file(PEM)
    ”’
    ret= xmlsec.cryptoAppKeyLoad(pri_key_file , xmlsec.KeyDataFormatPem,
                              None, None, None)
    ret.setName(pri_key_file)
    return ret

検証ルーチン

def _verify_xml(self,signed_xml_text,tmp_certfile=’/tmp/temp_cert.pem’):
    ”’
    Verify a signed XML
    ”’
    doc = libxml2.parseDoc(signed_xml_text.encode(‘UTF-8’))

    node = xmlsec.findNode(doc.getRootElement(),
                       xmlsec.NodeSignature, xmlsec.DSigNs)

    # create a temporal PEM file
    open(tmp_certfile,’w’).write( ‘—–BEGIN CERTIFICATE—–\n%s\n—–END CERTIFICATE—–\n’ %  (
        xmlsec.findNode(
            doc.getRootElement() , #libxml2.parseDoc(self.signed_xml.encode(‘UTF-8’)).getRootElement(),
            xmlsec.NodeX509Certificate,xmlsec.DSigNs).content
        ))

    # provide the Key Manager
    manager = self._load_trusted_certs(tmp_certfile)

    dsig_ctx = xmlsec.DSigCtx(manager )
    assert( dsig_ctx )
    assert( dsig_ctx.verify(node) >= 0 )
    assert( dsig_ctx.status == xmlsec.DSigStatusSucceeded )

    print "verification = OK! ",dsig_ctx.status

    return xmlsec.findNode(doc.getRootElement() , xmlsec.NodeSignatureValue,xmlsec.DSigNs).content

X.509の証明書をキーマネージャーに登録する

def _load_trusted_certs(self,certfile):
    manager = xmlsec.KeysMngr()
    assert(manager)

    assert( xmlsec.cryptoAppDefaultKeysMngrInit(manager) >= 0 )

    certs =  [ certfile ]

    for c in certs:
        print "loading ",c , "as a certificate to Key Manager…"
        assert( manager.certLoad(c,xmlsec.KeyDataFormatPem,
                     xmlsec.KeyDataTypeTrusted) >=0 )

    return manager

これらを使ってテスト。

    def testSignXml2(self):
        ”’
        TEST: Sign a very simple XML
        ”’
        src_xml =”'<?xml version="1.0" encoding="UTF-8"?>
<!–
testSignXMerialize()
–>
<Envelope xmlns="urn:envelope">
  <Data>
    Hello, World!
  </Data>
</Envelope>
”’
        print "testSignXml:"
        doc = self._sign_xml( self.rp.prikey,self.rp.cert , src_xml )
        signed= doc.serialize()
        print signed
        ret1=self._verify_xml(signed )

        doc = self._sign_xml( self.rp.prikey,self.rp.cert , src_xml ,True)
        signed= doc.serialize()
        print signed
        ret2= self._verify_xml(signed )

        print "same signature ?",(ret1==ret2)

実行結果

まず、ルート直に<Signature>

<?xml version="1.0" encoding="UTF-8"?>
<!–
testSignXMerialize()
–>
<Envelope xmlns="urn:envelope">
  <Data>
    Hello, World!
  </Data>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference>
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>BG5RjqaoAUu661eSbtxYc3T1WqQ=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>CoCs+9gUEA27vlzdunuvusTirIRYkV+t1cxdMsEFyj2hENZEfh8Ok6xSgstM0Hu6
8whFSpSXeO+8vcruMUnbsq7oCxNz+6/ezGYosFzFv3YAL5WtNkVstkXOJCnmBzMb
lOsoKTWcCp8BPvwBRt16vIpPCPipsAM162PaYdy1UXE=</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>MIIB/zCCAWgCCQCSwWCCsmugTTANBgkqhkiG9w0BAQUFADBEMRAwDgYDVQQDEwdy
cC5kZWIgMRQwEgYDVQQLEwtzeXMucnAuZGViIDENMAsGA1UEChMEc3lzIDELMAkG
A1UEBhMCSlAwHhcNMDkxMTI3MDgxMjE2WhcNMDkxMjI3MDgxMjE2WjBEMRAwDgYD
VQQDEwdycC5kZWIgMRQwEgYDVQQLEwtzeXMucnAuZGViIDENMAsGA1UEChMEc3lz
IDELMAkGA1UEBhMCSlAwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKUoVZoU
IBou8fqdPJ9wawbR4R+8VOwXzpwPwx79iMkFFYRoaiHNWQIVCHe0vmNiECmA1C53
L/Y5eGR60mJdq1HatNQuArBiCT2aQyLyYQiX7iZovNHIlKSTVsdEwqf19UxVVVtZ
g8D9FE58ZyOkDiALRkyl1IVa3U36Jo33IeaPAgMBAAEwDQYJKoZIhvcNAQEFBQAD
gYEAWwj2VRHEA7r6vSDaMrhaK707VZu41kbDvLNX6ELzqM/+7P916k3uL/zK/LkV
KdEcHXXyG5KPMfBeQDEVpDDmLECawWoSawLlpvc525TE5NrnTvHAbqOXVKMazt16
1Plpg7hM5okjKbSi5i+Vxe06X6BtRUJsT64c6oW6wE3iSCw=</X509Certificate>
</X509Data>
</KeyInfo>
</Signature></Envelope>

loading  /tmp/temp_cert.pem as a certificate to Key Manager…
verification = OK!  1

次に<Data>の下に<Signature>

<?xml version="1.0" encoding="UTF-8"?>
<!–
testSignXMerialize()
–>
<Envelope xmlns="urn:envelope">
  <Data>
    Hello, World!
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference>
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>BG5RjqaoAUu661eSbtxYc3T1WqQ=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>CoCs+9gUEA27vlzdunuvusTirIRYkV+t1cxdMsEFyj2hENZEfh8Ok6xSgstM0Hu6
8whFSpSXeO+8vcruMUnbsq7oCxNz+6/ezGYosFzFv3YAL5WtNkVstkXOJCnmBzMb
lOsoKTWcCp8BPvwBRt16vIpPCPipsAM162PaYdy1UXE=</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>MIIB/zCCAWgCCQCSwWCCsmugTTANBgkqhkiG9w0BAQUFADBEMRAwDgYDVQQDEwdy
cC5kZWIgMRQwEgYDVQQLEwtzeXMucnAuZGViIDENMAsGA1UEChMEc3lzIDELMAkG
A1UEBhMCSlAwHhcNMDkxMTI3MDgxMjE2WhcNMDkxMjI3MDgxMjE2WjBEMRAwDgYD
VQQDEwdycC5kZWIgMRQwEgYDVQQLEwtzeXMucnAuZGViIDENMAsGA1UEChMEc3lz
IDELMAkGA1UEBhMCSlAwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKUoVZoU
IBou8fqdPJ9wawbR4R+8VOwXzpwPwx79iMkFFYRoaiHNWQIVCHe0vmNiECmA1C53
L/Y5eGR60mJdq1HatNQuArBiCT2aQyLyYQiX7iZovNHIlKSTVsdEwqf19UxVVVtZ
g8D9FE58ZyOkDiALRkyl1IVa3U36Jo33IeaPAgMBAAEwDQYJKoZIhvcNAQEFBQAD
gYEAWwj2VRHEA7r6vSDaMrhaK707VZu41kbDvLNX6ELzqM/+7P916k3uL/zK/LkV
KdEcHXXyG5KPMfBeQDEVpDDmLECawWoSawLlpvc525TE5NrnTvHAbqOXVKMazt16
1Plpg7hM5okjKbSi5i+Vxe06X6BtRUJsT64c6oW6wE3iSCw=</X509Certificate>
</X509Data>
</KeyInfo>
</Signature></Data>
</Envelope>

loading  /tmp/temp_cert.pem as a certificate to Key Manager…
verification = OK!  1

両者の<SignatureValue>の比較

same signature ? True

カテゴリー: 未分類 パーマリンク

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中