问题
How can I verify Win8 inapp-purchase receipt, using xmlsec1? Here is what I'm tyring to do:
My sample receipt (saved in file
receipt.xml
):<?xml version="1.0"?> <Receipt Version="1.0" ReceiptDate="2012-08-30T23:10:05Z" CertificateId="b809e47cd0110a4db043b3f73e83acd917fe1336" ReceiptDeviceId="4e362949-acc3-fe3a-e71b-89893eb4f528"> <AppReceipt Id="8ffa256d-eca8-712a-7cf8-cbf5522df24b" AppId="55428GreenlakeApps.CurrentAppSimulatorEventTest_z7q3q7z11crfr" PurchaseDate="2012-06-04T23:07:24Z" LicenseType="Full" /> <ProductReceipt Id="6bbf4366-6fb2-8be8-7947-92fd5f683530" ProductId="Product1" PurchaseDate="2012-08-30T23:08:52Z" ExpirationDate="2012-09-02T23:08:49Z" ProductType="Durable" AppId="55428GreenlakeApps.CurrentAppSimulatorEventTest_z7q3q7z11crfr" /> <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/2001/04/xmldsig-more#rsa-sha256" /> <Reference URI=""> <Transforms> <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /> </Transforms> <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> <DigestValue>cdiU06eD8X/w1aGCHeaGCG9w/kWZ8I099rw4mmPpvdU=</DigestValue> </Reference> </SignedInfo> <SignatureValue>SjRIxS/2r2P6ZdgaR9bwUSa6ZItYYFpKLJZrnAa3zkMylbiWjh9oZGGng2p6/gtBHC2dSTZlLbqnysJjl7mQp/A3wKaIkzjyRXv3kxoVaSV0pkqiPt04cIfFTP0JZkE5QD/vYxiWjeyGp1dThEM2RV811sRWvmEs/hHhVxb32e8xCLtpALYx3a9lW51zRJJN0eNdPAvNoiCJlnogAoTToUQLHs72I1dECnSbeNPXiG7klpy5boKKMCZfnVXXkneWvVFtAA1h2sB7ll40LEHO4oYN6VzD+uKd76QOgGmsu9iGVyRvvmMtahvtL1/pxoxsTRedhKq6zrzCfT8qfh3C1w==</SignatureValue> </Signature>
Using
CertificateId
, I retrieve certificate using this url and save it to filecert
. Here are its contents:-----BEGIN CERTIFICATE----- MIIDyTCCArGgAwIBAgIQNP+YKvSo8IVArhlhpgc/xjANBgkqhkiG9w0BAQsFADCB jjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1Jl ZG1vbmQxHjAcBgNVBAoMFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEWMBQGA1UECwwN V2luZG93cyBTdG9yZTEgMB4GA1UEAwwXV2luZG93cyBTdG9yZSBMaWNlbnNpbmcw HhcNMTExMTE3MjMwNTAyWhcNMzYxMTEwMjMxMzQ0WjCBjjELMAkGA1UEBhMCVVMx EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1JlZG1vbmQxHjAcBgNVBAoM FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEWMBQGA1UECwwNV2luZG93cyBTdG9yZTEg MB4GA1UEAwwXV2luZG93cyBTdG9yZSBMaWNlbnNpbmcwggEiMA0GCSqGSIb3DQEB AQUAA4IBDwAwggEKAoIBAQCcr4/vgqZFtzMqy3jO0XHjBUNx6j7ZTXEnNpLl2VSe zVQA9KK2RlvroXKhYMUUdJpw+txm1mqi/W7D9QOYTq1e83GLhWC9IRh/OSmSYt0e kgVLB+icyRH3dtpYcJ5sspU2huPf4I/Nc06OuXlMsD9MU4Ug9IBD2HSDBEquhGRo xV64YuEH4645oB14LlEay0+JZlkKZ/mVhx/sdzSBfrda1X/Ckc7SOgnTSM3d/DnO 5DKwV2WYn+7i/rBqe4/op6IqQMrPpHyem9Sny+i0xiUMA+1IwkX0hs0gvHM6zDww TMDiTapbCy9LnmMx65oMq56hhsQydLEmquq8lVYUDEzLAgMBAAGjITAfMB0GA1Ud DgQWBBREzrOBz7zw+HWskxonOXAPMa6+NzANBgkqhkiG9w0BAQsFAAOCAQEAeVtN 4c6muxO6yfht9SaxEfleUBIjGfe0ewLBp00Ix7b7ldJ/lUQcA6y+Drrl7vjmkHQK OU3uZiFbCxTvgTcoz9o+1rzR/WPXmqH5bqu6ua/UrobGKavAScqqI/G6o56Xmx/y oErWN0VapN370crKJvNWxh3yw8DCl+W0EcVRiWX5lFsMBNBbVpK4Whp+VhkSJilu iRpe1B35Q8EqOz/4RQkOpVI0dREnuSYkBy/h2ggCtiQ5yfvH5zCdcfhFednYDevS axmt3W5WuHz8zglkg+OQ3qpXaXySRlrmLdxEmWu2MOiZbQkU2ZjBSQmvFAOy0dd6 P1YLS4+Eyh5drQJc0Q== -----END CERTIFICATE-----
And then I try this:
xmlsec1 --verify --print-debug --pubkey-cert-pem cert receipt.xml
. Here is the output:func=xmlSecOpenSSLEvpDigestVerify:file=digests.c:line=229:obj=sha256:subj=unknown:error=12:invalid data:data and digest do not match FAIL SignedInfo References (ok/all): 0/1 Manifests References (ok/all): 0/0 = VERIFICATION CONTEXT == Status: invalid == flags: 0x00000000 == flags2: 0x00000000 == Key Info Read Ctx: = KEY INFO READ CONTEXT == flags: 0x00000000 == flags2: 0x00000000 == enabled key data: all == RetrievalMethod level (cur/max): 0/1 == TRANSFORMS CTX (status=0) == flags: 0x00000000 == flags2: 0x00000000 == enabled transforms: all === uri: NULL === uri xpointer expr: NULL == EncryptedKey level (cur/max): 0/1 === KeyReq: ==== keyId: NULL ==== keyType: 0x00000000 ==== keyUsage: 0xffffffff ==== keyBitsSize: 0 === list size: 0 == Key Info Write Ctx: = KEY INFO WRITE CONTEXT == flags: 0x00000000 == flags2: 0x00000000 == enabled key data: all == RetrievalMethod level (cur/max): 0/1 == TRANSFORMS CTX (status=0) == flags: 0x00000000 == flags2: 0x00000000 == enabled transforms: all === uri: NULL === uri xpointer expr: NULL == EncryptedKey level (cur/max): 0/1 === KeyReq: ==== keyId: NULL ==== keyType: 0x00000001 ==== keyUsage: 0xffffffff ==== keyBitsSize: 0 === list size: 0 == Signature Transform Ctx: == TRANSFORMS CTX (status=0) == flags: 0x00000000 == flags2: 0x00000000 == enabled transforms: all === uri: NULL === uri xpointer expr: NULL === Transform: exc-c14n (href=http://www.w3.org/2001/10/xml-exc-c14n#) === Transform: rsa-sha256 (href=http://www.w3.org/2001/04/xmldsig-more#rsa-sha256) == Signature Method: === Transform: rsa-sha256 (href=http://www.w3.org/2001/04/xmldsig-more#rsa-sha256) == SignedInfo References List: === list size: 1 = REFERENCE VERIFICATION CONTEXT == Status: invalid == URI: "" == Reference Transform Ctx: == TRANSFORMS CTX (status=2) == flags: 0x00000000 == flags2: 0x00000000 == enabled transforms: all === uri: NULL === uri xpointer expr: NULL === Transform: enveloped-signature (href=http://www.w3.org/2000/09/xmldsig#enveloped-signature) === Transform: c14n (href=http://www.w3.org/TR/2001/REC-xml-c14n-20010315) === Transform: sha256 (href=http://www.w3.org/2001/04/xmlenc#sha256) === Transform: membuf-transform (href=NULL) == Digest Method: === Transform: sha256 (href=http://www.w3.org/2001/04/xmlenc#sha256) == Manifest References List: === list size: 0 Error: failed to verify file "receipt.xml"
Am I doing something wrong? What params should I provide to verify the receipt properly? Or is it indeed invalid (then can someone provide me with valid receipt?)?
回答1:
I found that verification succeeds if all of the extra whitespace is removed from receipt.xml
. If the file really does contain this when it's downloaded and saved, you may have to run the file through sed
or something to remove it (if it's actually there and you didn't just add it yourself accidentally).
# xmlsec1 --verify --print-debug --pubkey-cert-pem cert receipt.xml
OK
SignedInfo References (ok/all): 1/1
Manifests References (ok/all): 0/0
= VERIFICATION CONTEXT
== Status: succeeded
== flags: 0x00000000
== flags2: 0x00000000
== Key Info Read Ctx:
= KEY INFO READ CONTEXT
== flags: 0x00000000
== flags2: 0x00000000
== enabled key data: all
== RetrievalMethod level (cur/max): 0/1
== TRANSFORMS CTX (status=0)
== flags: 0x00000000
== flags2: 0x00000000
== enabled transforms: all
=== uri: NULL
=== uri xpointer expr: NULL
== EncryptedKey level (cur/max): 0/1
=== KeyReq:
==== keyId: rsa
==== keyType: 0x00000001
==== keyUsage: 0x00000002
==== keyBitsSize: 0
=== list size: 0
== Key Info Write Ctx:
= KEY INFO WRITE CONTEXT
== flags: 0x00000000
== flags2: 0x00000000
== enabled key data: all
== RetrievalMethod level (cur/max): 0/1
== TRANSFORMS CTX (status=0)
== flags: 0x00000000
== flags2: 0x00000000
== enabled transforms: all
=== uri: NULL
=== uri xpointer expr: NULL
== EncryptedKey level (cur/max): 0/1
=== KeyReq:
==== keyId: NULL
==== keyType: 0x00000001
==== keyUsage: 0xffffffff
==== keyBitsSize: 0
=== list size: 0
== Signature Transform Ctx:
== TRANSFORMS CTX (status=2)
== flags: 0x00000000
== flags2: 0x00000000
== enabled transforms: all
=== uri: NULL
=== uri xpointer expr: NULL
=== Transform: exc-c14n (href=http://www.w3.org/2001/10/xml-exc-c14n#)
=== Transform: rsa-sha256 (href=http://www.w3.org/2001/04/xmldsig-more#rsa-sha256)
=== Transform: membuf-transform (href=NULL)
== Signature Method:
=== Transform: rsa-sha256 (href=http://www.w3.org/2001/04/xmldsig-more#rsa-sha256)
== Signature Key:
== KEY
=== method: RSAKeyValue
=== key type: Private
=== key usage: -1
=== rsa key: size = 2048
=== list size: 1
=== X509 Data:
==== Certificate:
==== Subject Name: /C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/OU=Windows Store/CN=Windows Store Licensing
==== Issuer Name: /C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/OU=Windows Store/CN=Windows Store Licensing
==== Issuer Serial: 34FF982AF4A8F08540AE1961A6073FC6
== SignedInfo References List:
=== list size: 1
= REFERENCE VERIFICATION CONTEXT
== Status: succeeded
== URI: ""
== Reference Transform Ctx:
== TRANSFORMS CTX (status=2)
== flags: 0x00000000
== flags2: 0x00000000
== enabled transforms: all
=== uri: NULL
=== uri xpointer expr: NULL
=== Transform: enveloped-signature (href=http://www.w3.org/2000/09/xmldsig#enveloped-signature)
=== Transform: c14n (href=http://www.w3.org/TR/2001/REC-xml-c14n-20010315)
=== Transform: sha256 (href=http://www.w3.org/2001/04/xmlenc#sha256)
=== Transform: membuf-transform (href=NULL)
== Digest Method:
=== Transform: sha256 (href=http://www.w3.org/2001/04/xmlenc#sha256)
== Manifest References List:
=== list size: 0
Remember that the signature is valid for the exact file, character for character. Any changes to the file, even whitespace for formatting, will invalidate the signature. I suspect that there is some formatting going on when you opened the file, maybe you saved it with that formatting.
Edit
I forgot that you're also missing the closing tag in what you posted for receipt.xml
. I suspect it's there in your copy of the file, though, since xmlsec1
would have told you so if it wasn't (as it told me; I had to manually add it).
Try xmllint --noblanks --output receipt.xml receipt.xml
to remove the unwanted spaces and CR/LFs.
来源:https://stackoverflow.com/questions/22912647/verifying-windows-8-inapp-purchase-receipt-with-xmlsec1