如何在服务器端用Java验证windows phone应用内购买?

如何在服务器端用Java验证windows phone应用内购买?,java,windows-phone-8,in-app-purchase,windows-phone,Java,Windows Phone 8,In App Purchase,Windows Phone,根据示例: 应验证的xml文件是: <?xml version="1.0"?> <Receipt Version="1.0" CertificateId="A656B9B1B3AA509EEA30222E6D5E7DBDA9822DCD" xmlns="http://schemas.microsoft.com/windows/2012/store/receipt"> <ProductReceipt PurchasePrice="$20.89" PurchaseDat

根据示例:

应验证的xml文件是:

<?xml version="1.0"?>
<Receipt Version="1.0" CertificateId="A656B9B1B3AA509EEA30222E6D5E7DBDA9822DCD" xmlns="http://schemas.microsoft.com/windows/2012/store/receipt">
<ProductReceipt PurchasePrice="$20.89" PurchaseDate="2012-11-30T21:32:07.096Z" Id="2f9c5c8f-3e1d-4fc7-a871-ac58f7e78053" AppId="3ec6cd9a-ca82-4d38-bfdf-ecafdb35a738" ProductId="Test" ProductType="Consumable" PublisherDeviceId="Test" MicrosoftProductId="59ef70aa-7099-4679-889e-f21919bfd2c6" />
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
  <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
  <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>FyFb1HGm+yeOIjt18M6TPD4Qzeu469vwDbQs7w72mdA=</DigestValue>
  </Reference>
</SignedInfo>    
 <SignatureValue>noct5CYBtRwBxVxkUeZIzeDyruLGVBqBMuFuBytpouPLACnQ5dbzdRvWX4XN67IUo0J2FW8DoYcMbf3sAS+PeKKV8SLnU+l8K1hWEbbbugHZezStTzwwkYcZuCTnAk7BYO0aiZWuXm9GiZGT9iyXsYtU1/u87L+llnVibU/m7gV8tD3vG0tVkjzV20C8666mHUsY/jxeq3ed7YY9CT0SDrh5PeL4ESaopBLcncHo/e6lcjyoKbO3e6YuIpsi8DVueeKNhpTlwa5yc0O3qzc5SGnT4Kbhj9NBEXf15/oTaLlg7lJhnQZ0mY+yR8vc4D0SkqD6e5Uc4u64hnu+g3Hphg==</SignatureValue>
</Signature>
</Receipt>

FyFb1HGm+yeOIjt18M6TPD4Qzeu469vwDbQs7w72mdA=
2.中国政府对中国的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市,一些城市的一些城市的一些城市的一些城市,一些城市的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市,一些城市的一些城市的一些城市的一些城市的一些城市的一些城市,一些城市的一些城市的一些城市的一些城市,一些城市的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市,他们的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市,他们的一些城市的一些城市的一些城市的一些城市,他们的一些城市的一些城市的一些城市的一些城市,他们的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市。他们的一些城市的一些城市的一些城市的一些城市的一些城市。他们他们他们他们他们的一些城市。他们他们的一些城市的一些城市的一些城市的一些城市的一些城市4U64HNU+g3Hphg==
我可以从.cer文件中获取pulbic密钥:

<Modulus>29AnpbVajjiCYsDRoAK+2dCuKwGLBwmtaEhTyV7aJM9d+G4tp3ifGxyCgJ09JMGt8VYlMcKd/jmXdrdj7IQ79LnGeXbrOlgp7gMPzB1QKHYC0DKmIinjO1UyIt0tbN4lf+umPCj+4x9wphNlwlzkGnvm0FLshrE4rdEnFO/jKHzg6DYbzjbOeJ/ytVlZ3LdsFgaZ/BhgEvpdpszhdI12zEo7c+8Liu+xnsnRvsfaWi7hyMgrKO7Yzqr/5b6JeSCF9FZwuRtrwunVkejJDS+Rcy157ErkIKGBFGVz5VyYbJr+qMsnp2j9D6WCWXAiy1YtS9oXFaPAdgyBINyN7fHIfw==</Modulus>
<Exponent>AQAB</Exponent>
《代码>29《代码>29《代码>29《代码>29》一书中的一篇文章中的一篇文章中的一篇文章中的一篇文章中的一篇文章中的一篇文章中的一篇文章中的一篇文章中的一篇文章中的一篇文章中的一篇文章中的一篇文章中的一篇文章中的两篇文章中的一篇文章中的两篇文章中的两篇文章中的两篇文章中的两篇文章中的两篇文章中的两篇文章中的两篇文章中的两篇文章中的两篇文章中的两篇文章中的两篇文章中的两篇文章中的两篇文章中的两篇文章中的两篇文章中的两篇文章中的两篇文章中的两篇文章中的两篇文章,一篇文章中的两篇文章中的两篇文章,一篇文章中的两篇文章,一篇文章的两篇文章中的两篇文章中的两篇文章中的两篇文章中的两篇文章,YTS9OxfapadGybinYN7FHIFW== AQAB 我想在我的java服务器上进行验证。我在这里得到了一个示例代码:。 然后,我根据以下内容对xml文件进行了一些小更改:


FyFb1HGm+yeOIjt18M6TPD4Qzeu469vwDbQs7w72mdA=
2.中国政府对中国的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市,一些城市的一些城市的一些城市的一些城市,一些城市的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市,一些城市的一些城市的一些城市的一些城市的一些城市的一些城市,一些城市的一些城市的一些城市的一些城市,一些城市的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市,他们的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市,他们的一些城市的一些城市的一些城市的一些城市,他们的一些城市的一些城市的一些城市的一些城市,他们的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市的一些城市。他们的一些城市的一些城市的一些城市的一些城市的一些城市。他们他们他们他们他们的一些城市。他们他们的一些城市的一些城市的一些城市的一些城市的一些城市4U64HNU+g3Hphg==
Miidfdccagcgawibagiqrih3cql1cgplfusFjstajbgurdg8hTbGnVbamTfelHcFjl2VpChrQCM9kdWn0Aw9Umb4xDdTdHdDcGnzyFbGdGdGfBy2y2Y3RpB24WgGeima0GCSqIb3dQeQeQeQeQeQeQeQoIb0Ib0Ib0Ib0Ib0CelQoIbQoIbQoIbQoIbQoIb0OijiWnGyWnGyWnGd7WnGd7WnGd7WnGdGdGd7KdKdKdKdKdKdKdKKdKdKdK4KdKdKdKdKd4.6 6 6六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六六十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十十SEL1CGPLFUSFJSTAJBG在这一领域中,研究者+研究+加上了一个10年的研究。目前,该领域的研究+研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究4 4年的非研究4年的非研究4月4月8月10月的研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究+非研究/非研究/非研究/非研究/准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准ZXFQMVZMIBMFYJ/y89PLs/ewHopSK7vQmGFjfjIl
2.一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个关于一个OxfapadGybinyN7FHIFW==
AQAB
但是验证失败了。我找不到解决办法。请帮忙

我的java代码如下:

import javax.xml.crypto.*;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dom.*;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.crypto.dsig.keyinfo.*;
import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.security.*;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/**
 * This is a simple example of validating an XML
 * Signature using the JSR 105 API. It assumes the key needed to
 * validate the signature is contained in a KeyValue KeyInfo.
 */
public class ValidateXMLwithCertificate {

//
// Synopsis: java Validate [document]
//
//    where "document" is the name of a file containing the XML document
//    to be validated.
//
public static void main(String[] args) throws Exception {

    // Instantiate the document to be validated
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    Document doc =
        dbf.newDocumentBuilder().parse(new FileInputStream("./ReceiptSHA256.xml"));
    // Find Signature element
    NodeList nl =
        doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
    if (nl.getLength() == 0) {
        throw new Exception("Cannot find Signature element");
    }
    NodeList nl2 =
            doc.getElementsByTagNameNS(XMLSignature.XMLNS, "KeyInfo");
        if (nl2.getLength() == 0) {
            throw new Exception("Cannot find KeyInfo element");
        }
    // Create a DOM XMLSignatureFactory that will be used to unmarshal the
    // document containing the XMLSignature
    XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");

    // Create a DOMValidateContext and specify a KeyValue KeySelector
    // and document context
    DOMValidateContext valContext = new DOMValidateContext
        (new KeyValueKeySelector(), nl.item(0));

    // unmarshal the XMLSignature
    XMLSignature signature = fac.unmarshalXMLSignature(valContext);

    // Validate the XMLSignature (generated above)
    boolean coreValidity = signature.validate(valContext);

    // Check core validation status
    if (coreValidity == false) {
        System.err.println("Signature failed core validation");
        boolean sv = signature.getSignatureValue().validate(valContext);
        System.out.println("signature validation status: " + sv);
        // check the validation status of each Reference
        Iterator i = signature.getSignedInfo().getReferences().iterator();
        for (int j=0; i.hasNext(); j++) {
            boolean refValid =
                ((Reference) i.next()).validate(valContext);
            System.out.println("ref["+j+"] validity status: " + refValid);
        }
    } else {
        System.out.println("Signature passed core validation");
    }
}

/**
 * KeySelector which retrieves the public key out of the
 * KeyValue element and returns it.
 * NOTE: If the key algorithm doesn't match signature algorithm,
 * then the public key will be ignored.
 */
private static class KeyValueKeySelector extends KeySelector {
    public KeySelectorResult select(KeyInfo keyInfo,
                                    KeySelector.Purpose purpose,
                                    AlgorithmMethod method,
                                    XMLCryptoContext context)
        throws KeySelectorException {

        System.out.println(keyInfo + " " + method);


        if (keyInfo == null) {
            throw new KeySelectorException("Null KeyInfo object!");
        }

        SignatureMethod sm = (SignatureMethod) method;
        List list = keyInfo.getContent();

        for (int i = 0; i < list.size(); i++) {
            XMLStructure xmlStructure = (XMLStructure) list.get(i);
            if (xmlStructure instanceof KeyValue) {
                PublicKey pk = null;
                try {
                    pk = ((KeyValue)xmlStructure).getPublicKey();
                    System.out.println(pk);
                } catch (KeyException ke) {
                    throw new KeySelectorException(ke);
                }
                System.out.println(sm.getAlgorithm() + " -------- " +  pk.getAlgorithm());
                // make sure algorithm is compatible with method
                if (algEquals(sm.getAlgorithm(), pk.getAlgorithm())) {
                    return new SimpleKeySelectorResult(pk);
                }
            }
        }
        throw new KeySelectorException("No KeyValue element found!");
    }

    //@@@FIXME: this should also work for key types other than DSA/RSA
    static boolean algEquals(String algURI, String algName) {

        XMLSignatureFactory factory = XMLSignatureFactory.getInstance();
        SignatureMethod sm = null;
        try {
            sm = 
                    factory.newSignatureMethod
                        ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", 
                         (SignatureMethodParameterSpec) null);
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println("algURI:" + algURI + " algName:" + algName + " SHa1:" + sm.getAlgorithm());
        if (algName.equalsIgnoreCase("DSA") &&
            algURI.equalsIgnoreCase(SignatureMethod.DSA_SHA1)) {
            return true;
        } else if (algName.equalsIgnoreCase("RSA") &&
                   algURI.equalsIgnoreCase(sm.getAlgorithm())) {
            System.out.println("will return true");
            return true;
        } else {
            return false;
        }
    }
}

private static class SimpleKeySelectorResult implements KeySelectorResult {
    private PublicKey pk;
    SimpleKeySelectorResult(PublicKey pk) {
        this.pk = pk;
    }

    public Key getKey() { return pk; }
}
}
import javax.xml.crypto.*;
导入javax.xml.crypto.dsig.*;
导入javax.xml.crypto.dom.*;
导入javax.xml.crypto.dsig.dom.DOMValidateContext;
导入javax.xml.crypto.dsig.keyinfo.*;
导入javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;
导入java.io.FileInputStream;
导入java.io.FileNotFoundException;
导入java.security.*;
导入java.security.cert.CertificateFactory;
导入java.security.cert.x509证书;
导入java.util.Collections;
导入java.util.Iterator;
导入java.util.List;
导入javax.xml.parsers.DocumentBuilderFactory;
导入org.w3c.dom.Document;
导入org.w3c.dom.Node;
导入org.w3c.dom.NodeList;
/**
*这是一个验证XML的简单示例
*使用JSR105API进行签名。它假定需要
*验证签名是否包含在KeyValue KeyInfo中。
*/
公共类ValidateXMLwithCertificate{
//
//简介:java验证[文档]
//
//其中“document”是包含XML文档的文件的名称
//待验证。
//
公共静态void main(字符串[]args)引发异常{
//实例化要验证的文档
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
文件文件=
解析(新文件输入流(“./ReceiptSHA256.xml”);
//查找签名元素
节点列表nl=
getelementsbytagnames文件(XMLSignature.XMLNS,“签名”);
如果(nl.getLength()==0){
抛出新异常(“找不到签名元素”);
}
节点列表nl2=
getelementsbytagnames文件(XMLSignature.XMLNS,“KeyInfo”);
如果(nl2.getLength()==0){
抛出新异常(“找不到KeyInfo元素”);
}
//创建一个DOM XMLSignatureFactory,用于解组
//包含XML签名的文档
XMLSignatureFactory fac=XMLSignatureFactory.getInstance(“DOM”);
//创建DOMValidateContext并指定KeyValue KeySelector
//和文档上下文
DOMValidateContext=new DOMValidateContext
(新的KeyValueKeySelector(),nl.项(0));
//解组XML签名
XMLSignature signature=fac.unmarshalXMLSignature(valContext);
//验证XMLSignature(上面生成的)
布尔coreValidity=signature.validate(valContext);
//检查核心验证状态
如果(coreValidity==false){
System.err.println(“签名未通过核心验证”);
布尔sv=signature.getSignatureValue().validate(valContext);
System.out.println(“签名验证状态:+sv”);
//检查每个参考的验证状态
迭代器i=signature.getSignedInfo().getReferences().Iterator();
对于(int j=0;i.hasNext();j++){
布尔refValid=
((参考
import javax.xml.crypto.*;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dom.*;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.crypto.dsig.keyinfo.*;
import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.security.*;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/**
 * This is a simple example of validating an XML
 * Signature using the JSR 105 API. It assumes the key needed to
 * validate the signature is contained in a KeyValue KeyInfo.
 */
public class ValidateXMLwithCertificate {

//
// Synopsis: java Validate [document]
//
//    where "document" is the name of a file containing the XML document
//    to be validated.
//
public static void main(String[] args) throws Exception {

    // Instantiate the document to be validated
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    Document doc =
        dbf.newDocumentBuilder().parse(new FileInputStream("./ReceiptSHA256.xml"));
    // Find Signature element
    NodeList nl =
        doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
    if (nl.getLength() == 0) {
        throw new Exception("Cannot find Signature element");
    }
    NodeList nl2 =
            doc.getElementsByTagNameNS(XMLSignature.XMLNS, "KeyInfo");
        if (nl2.getLength() == 0) {
            throw new Exception("Cannot find KeyInfo element");
        }
    // Create a DOM XMLSignatureFactory that will be used to unmarshal the
    // document containing the XMLSignature
    XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");

    // Create a DOMValidateContext and specify a KeyValue KeySelector
    // and document context
    DOMValidateContext valContext = new DOMValidateContext
        (new KeyValueKeySelector(), nl.item(0));

    // unmarshal the XMLSignature
    XMLSignature signature = fac.unmarshalXMLSignature(valContext);

    // Validate the XMLSignature (generated above)
    boolean coreValidity = signature.validate(valContext);

    // Check core validation status
    if (coreValidity == false) {
        System.err.println("Signature failed core validation");
        boolean sv = signature.getSignatureValue().validate(valContext);
        System.out.println("signature validation status: " + sv);
        // check the validation status of each Reference
        Iterator i = signature.getSignedInfo().getReferences().iterator();
        for (int j=0; i.hasNext(); j++) {
            boolean refValid =
                ((Reference) i.next()).validate(valContext);
            System.out.println("ref["+j+"] validity status: " + refValid);
        }
    } else {
        System.out.println("Signature passed core validation");
    }
}

/**
 * KeySelector which retrieves the public key out of the
 * KeyValue element and returns it.
 * NOTE: If the key algorithm doesn't match signature algorithm,
 * then the public key will be ignored.
 */
private static class KeyValueKeySelector extends KeySelector {
    public KeySelectorResult select(KeyInfo keyInfo,
                                    KeySelector.Purpose purpose,
                                    AlgorithmMethod method,
                                    XMLCryptoContext context)
        throws KeySelectorException {

        System.out.println(keyInfo + " " + method);


        if (keyInfo == null) {
            throw new KeySelectorException("Null KeyInfo object!");
        }

        SignatureMethod sm = (SignatureMethod) method;
        List list = keyInfo.getContent();

        for (int i = 0; i < list.size(); i++) {
            XMLStructure xmlStructure = (XMLStructure) list.get(i);
            if (xmlStructure instanceof KeyValue) {
                PublicKey pk = null;
                try {
                    pk = ((KeyValue)xmlStructure).getPublicKey();
                    System.out.println(pk);
                } catch (KeyException ke) {
                    throw new KeySelectorException(ke);
                }
                System.out.println(sm.getAlgorithm() + " -------- " +  pk.getAlgorithm());
                // make sure algorithm is compatible with method
                if (algEquals(sm.getAlgorithm(), pk.getAlgorithm())) {
                    return new SimpleKeySelectorResult(pk);
                }
            }
        }
        throw new KeySelectorException("No KeyValue element found!");
    }

    //@@@FIXME: this should also work for key types other than DSA/RSA
    static boolean algEquals(String algURI, String algName) {

        XMLSignatureFactory factory = XMLSignatureFactory.getInstance();
        SignatureMethod sm = null;
        try {
            sm = 
                    factory.newSignatureMethod
                        ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", 
                         (SignatureMethodParameterSpec) null);
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println("algURI:" + algURI + " algName:" + algName + " SHa1:" + sm.getAlgorithm());
        if (algName.equalsIgnoreCase("DSA") &&
            algURI.equalsIgnoreCase(SignatureMethod.DSA_SHA1)) {
            return true;
        } else if (algName.equalsIgnoreCase("RSA") &&
                   algURI.equalsIgnoreCase(sm.getAlgorithm())) {
            System.out.println("will return true");
            return true;
        } else {
            return false;
        }
    }
}

private static class SimpleKeySelectorResult implements KeySelectorResult {
    private PublicKey pk;
    SimpleKeySelectorResult(PublicKey pk) {
        this.pk = pk;
    }

    public Key getKey() { return pk; }
}
}