数字签名是使数字内容真实可信的一种广泛使用的机制。 通过为某些内容生成数字签名,我们可以让另一方能够验证该内容。 通过此验证,它可以保证在我们签名后不会更改。 通过这个示例,我将分享如何为SOAP信封生成签名。 但是,这当然也适用于任何其他内容签名。
在这里,我将签名
- SOAP信封本身
- 一个附件
- 将签名放在SOAP标头中
通过将签名放置在也由签名签名的SOAP标头中,这成为封装签名的演示。
我正在使用Apache Santuario库进行签名。 以下是我使用的代码段。 我已经在此处共享了完整的示例以供下载 。
public static void main(String unused[]) throws Exception {
String keystoreType = "JKS";
String keystoreFile = "src/main/resources/PushpalankaKeystore.jks";
String keystorePass = "pushpalanka";
String privateKeyAlias = "pushpalanka";
String privateKeyPass = "pushpalanka";
String certificateAlias = "pushpalanka";
File signatureFile = new File("src/main/resources/signature.xml");
Element element = null;
String BaseURI = signatureFile.toURI().toURL().toString();
//SOAP envelope to be signed
File attachmentFile = new File("src/main/resources/sample.xml");
//get the private key used to sign, from the keystore
KeyStore ks = KeyStore.getInstance(keystoreType);
FileInputStream fis = new FileInputStream(keystoreFile);
ks.load(fis, keystorePass.toCharArray());
PrivateKey privateKey =
(PrivateKey) ks.getKey(privateKeyAlias, privateKeyPass.toCharArray());
//create basic structure of signature
javax.xml.parsers.DocumentBuilderFactory dbf =
javax.xml.parsers.DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(attachmentFile);
XMLSignature sig =
new XMLSignature(doc, BaseURI, XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1);
//optional, but better
element = doc.getDocumentElement();
element.normalize();
element.getElementsByTagName("soap:Header").item(0).appendChild(sig.getElement());
{
Transforms transforms = new Transforms(doc);
transforms.addTransform(Transforms.TRANSFORM_C14N_OMIT_COMMENTS);
//Sign the content of SOAP Envelope
sig.addDocument("", transforms, Constants.ALGO_ID_DIGEST_SHA1);
//Adding the attachment to be signed
sig.addDocument("../resources/attachment.xml", transforms, Constants.ALGO_ID_DIGEST_SHA1);
}
//Signing procedure
{
X509Certificate cert =
(X509Certificate) ks.getCertificate(certificateAlias);
sig.addKeyInfo(cert);
sig.addKeyInfo(cert.getPublicKey());
sig.sign(privateKey);
}
//write signature to file
FileOutputStream f = new FileOutputStream(signatureFile);
XMLUtils.outputDOMc14nWithComments(doc, f);
f.close();
}
首先,它读入用于签名的私钥。 要为您自己创建密钥对, 这篇文章会有所帮助。 然后,它创建了签名,并添加了SOAP消息和附件作为要签名的文档。 最后,它执行签名并将签名的文档写入文件。
签名的SOAP消息如下所示。
<soap:Envelope xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:pj="http://www.pjxml.org/namespaces/messageHeader"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance">
<soap:Header>
<pj:MessageHeader pj:version="1.0" soap:mustUnderstand="1">
<pj:From>
<pj:PartyId pj:type="ABCDE">FUN</pj:PartyId>
</pj:From>
<pj:To>
<pj:PartyId pj:type="ABCDE">PARTY</pj:PartyId>
</pj:To>
<pj:CPAId>uri:www.pjxml.org/socialService/Ping</pj:CPAId>
<pj:ConversationId>FUN PARTY FUN 59c64t0087fg3kfs000003n9</pj:ConversationId>
<pj:Service>uri:www.pjxml.org/socialService/</pj:Service>
<pj:Action>Ping</pj:Action>
<pj:MessageData>
<pj:MessageId>FUN 59c64t0087fg3kfs000003n9</pj:MessageId>
<pj:Timestamp>2013-10-22T17:12:20</pj:Timestamp>
</pj:MessageData>
</pj:MessageHeader>
<pj:Via pj:id="59c64t0087fg3ki6000003na" pj:syncReply="False" pj:version="1.0"
soap:actor="http://schemas.xmlsoap.org/soap/actor/next" soap:mustUnderstand="1">
<pj:Service>uri:www.pjxml.org/socialService/</pj:Service>
<pj:Action>Ping</pj:Action>
</pj:Via>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod>
<ds:Reference URI="">
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
<ds:DigestValue>9RXY9kp/Klx36gd4BULvST4qffI=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="../resources/attachment.xml">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
<ds:DigestValue>3JcccO8+0bCUUR3EJxGJKJ+Wrbc=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>d0hBQLIvZ4fwUZlrsDLDZojvwK2DVaznrvSoA/JTjnS7XZ5oMplN9 THX4xzZap3+WhXwI2xMr3GKO................x7u+PQz1UepcbKY3BsO8jB3dxWN6r+F4qTyWa+xwOFxqLj546WX35f8zT4GLdiJI5oiYeo1YPLFFqTrwg==
</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate> MIIDjTCCAnWgAwIBAgIEeotzFjANBgkqhkiG9w0BAQsFADB3MQswCQYDVQQGEwJMSzEQMA4GA1UE...............qXfD/eY+XeIDyMQocRqTpcJIm8OneZ8vbMNQrxsRInxq+DsG+C92b
</ds:X509Certificate>
</ds:X509Data>
<ds:KeyValue>
<ds:RSAKeyValue>
<ds:Modulus>
k5y0amGgOQ2O/St0Kc2/xye80tX2fDEKs2YOlM/zCknL8VgK0CbAKVAwvJoycQL9mGRkPDmbitHe............StGofmsoKURzo8hofYEn41rGsq5wCuqJhhHYGDrPpFcuJiuI3SeXgcMtBnMwsIaKv2uHaPRbNX31WEuabuv6Q==
</ds:Modulus>
<ds:Exponent>AQAB</ds:Exponent>
</ds:RSAKeyValue>
</ds:KeyValue>
</ds:KeyInfo>
</ds:Signature>
</soap:Header>
<soap:Body>
<pr:GetPriceResponse xmlns:pr="http://www.pushpalankajaya.com/prices">
<pr:Price>1.90</pr:Price>
</pr:GetPriceResponse>
</soap:Body>
</soap:Envelope>
在下一篇文章中,让我们看看如何验证此签名,以便我们可以保证签名的文档不会更改。
干杯!