Цифровая подпись является широко используемым механизмом аутентификации цифрового контента. Создавая цифровую подпись для некоторого контента, мы можем позволить другой стороне проверить ее. Это может обеспечить гарантию того, что эта проверка не будет изменена после того, как мы ее подписали. В этом примере я расскажу, как создать подпись для конверта SOAP. Но, конечно, это справедливо и для подписи любого другого контента.
Здесь я подпишу
- Сам конверт SOAP
- Приложение
- Поместите подпись в заголовок SOAP
С размещением подписи внутри заголовка SOAP, который также подписан подписью, это становится демонстрацией завернутой подписи.
Я использую библиотеку Apache Santuario для подписи. Ниже приведен фрагмент кода, который я использовал. Я поделился полным образцом здесь, чтобы его можно было скачать .
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
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-сообщение выглядит следующим образом.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
< soap:Envelope xmlns:dsig = "http://www.w3.org/2000/09/xmldsig#" xmlns:pj = "http://www.pjxml.org/namespaces/messageHeader" < 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" < pj:Service >uri:www.pjxml.org/socialService/</ pj:Service > < pj:Action >Ping</ pj:Action > </ pj:Via > < ds:SignedInfo > < ds:CanonicalizationMethod < ds:Reference URI = "" > < ds:DigestValue >9RXY9kp/Klx36gd4BULvST4qffI=</ ds:DigestValue > </ ds:Reference > < ds:Reference URI = "../resources/attachment.xml" > < ds:Transforms > </ ds:Transforms > < 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:Price >1.90</ pr:Price > </ pr:GetPriceResponse > </ soap:Body > </ soap:Envelope > |
В следующем посте мы увидим, как проверить эту подпись, чтобы мы могли гарантировать, что подписанные документы не будут изменены.
Ура!