根据示例:http://code.msdn.microsoft.com/wpapps/In-app-purchase-receipt-c3e0bce4
应验证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>
我可以从.cer文件中获取pulbic密钥:
<Modulus>29AnpbVajjiCYsDRoAK+2dCuKwGLBwmtaEhTyV7aJM9d+G4tp3ifGxyCgJ09JMGt8VYlMcKd/jmXdrdj7IQ79LnGeXbrOlgp7gMPzB1QKHYC0DKmIinjO1UyIt0tbN4lf+umPCj+4x9wphNlwlzkGnvm0FLshrE4rdEnFO/jKHzg6DYbzjbOeJ/ytVlZ3LdsFgaZ/BhgEvpdpszhdI12zEo7c+8Liu+xnsnRvsfaWi7hyMgrKO7Yzqr/5b6JeSCF9FZwuRtrwunVkejJDS+Rcy157ErkIKGBFGVz5VyYbJr+qMsnp2j9D6WCWXAiy1YtS9oXFaPAdgyBINyN7fHIfw==</Modulus>
<Exponent>AQAB</Exponent>
我想在我的java服务器上进行验证。我在这里得到了一个示例代码:http://docs.oracle.com/javase/7/docs/technotes/guides/security/xmldsig/Validate.java。 然后我根据:Validate XML signature JAVA
对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>
<KeyInfo>
<X509Data> <X509Certificate>MIIDFDCCAgCgAwIBAgIQrih3cQuSeL1CgpLFusfJsTAJBgUrDgMCHQUAMB8xHTAbBgNVBAMTFElhcFJlY2VpcHRQcm9kdWN0aW9uMB4XDTEyMDIxNzAxMTYyNFoXDTM5MTIzMTIzNTk1OVowHzEdMBsGA1UEAxMUSWFwUmVjZWlwdFByb2R1Y3Rpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDb0CeltVqOOIJiwNGgAr7Z0K4rAYsHCa1oSFPJXtokz134bi2neJ8bHIKAnT0kwa3xViUxwp3+OZd2t2PshDv0ucZ5dus6WCnuAw/MHVAodgLQMqYiKeM7VTIi3S1s3iV/66Y8KP7jH3CmE2XCXOQae+bQUuyGsTit0ScU7+MofODoNhvONs54n/K1WVnct2wWBpn8GGAS+l2mzOF0jXbMSjtz7wuK77GeydG+x9paLuHIyCso7tjOqv/lvol5IIX0VnC5G2vC6dWR6MkNL5FzLXnsSuQgoYEUZXPlXJhsmv6oyyenaP0PpYJZcCLLVi1L2hcVo8B2DIEg3I3t8ch/AgMBAAGjVDBSMFAGA1UdAQRJMEeAEHGLK3BRpCWDa2vU50kI73ehITAfMR0wGwYDVQQDExRJYXBSZWNlaXB0UHJvZHVjdGlvboIQrih3cQuSeL1CgpLFusfJsTAJBgUrDgMCHQUAA4IBAQC4jmOu0H3j7AwVBvpQzPMLBd0GTimBXmJw+nruE+0Hh/0ywGTFNE+KcQ21L4v+IuP8iMh3lpOcPb23ucuaoNSdWi375/KxrW831dbh+goqCZP7mWbxpnSnFnuV+R1VPsQjdS+0tg5gjDKNMSx/2fH8krLAkidJ7rvUNmtEWMeVNk0/ZM/ECinobMSSwbqUuc9Qql9T1epe+xv34a6eek+m4W0VXnLSuKhQS5jdILsyeJWHROZF5mrh3DQuS0Ll5FzKmJxHf0hyXAo03SSA+x3JphAU4oYbkE9nRTU1tR6iq1D9ZxfQmvzmIbMfyJ/y89PLs/ewHopSK7vQmGFjfjIl</X509Certificate></X509Data>
<KeyValue>
<RSAKeyValue>
<Modulus>29AnpbVajjiCYsDRoAK+2dCuKwGLBwmtaEhTyV7aJM9d+G4tp3ifGxyCgJ09JMGt8VYlMcKd/jmXdrdj7IQ79LnGeXbrOlgp7gMPzB1QKHYC0DKmIinjO1UyIt0tbN4lf+umPCj+4x9wphNlwlzkGnvm0FLshrE4rdEnFO/jKHzg6DYbzjbOeJ/ytVlZ3LdsFgaZ/BhgEvpdpszhdI12zEo7c+8Liu+xnsnRvsfaWi7hyMgrKO7Yzqr/5b6JeSCF9FZwuRtrwunVkejJDS+Rcy157ErkIKGBFGVz5VyYbJr+qMsnp2j9D6WCWXAiy1YtS9oXFaPAdgyBINyN7fHIfw==</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>
</Signature>
</Receipt>
但验证失败了。我找不到解决方案。 Plz帮助。
我的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; }
}
}
答案 0 :(得分:0)
最后,我删除了所有空格或“&n”之间的“\ n”后验证成功和“&lt;”。