我的知识库

知识等于力量

« MyEclipse 5.5GA的破解程序关于ESB的开发实践小结 »

对 Atom 进行签名,加密和解密

2007 年 6 月 25 日

Atom 是一种用于传递信息的极好的格式,但是其安全性如何呢?XML 数字签名(XML Digital Signature)能确保数据来自于受信任方且未被修改,同时 XML 加密(XML Encryption)能保护敏感信息不被窥窃。但是如何才能在不破坏 Atom 结构的情况下使用这些技术呢?这篇文章介绍了如何使用 Apache Abdera API 轻易地实现数字签名和加密与 Atom 的紧密结合。

准备工作

阅读本文需对 Atom 联合格式内部的概念有一定的熟悉和了解。您也应该至少对 XML 安全内部的概念有些许了解,但是对此并不做硬性要求。

要使用本文所演示的例子,您需要从 http://incubator.apache.org/abdera/ 处下载 Apache Abdera 程序包,使用它可以简化对 Atom 数据的操作。还需要从 http://xml.apache.org/security/download.html 处下载 Apache 的 XML 安全实现。要设置环境,需要把这两个程序包中的所有 *.jar 文件添加到您的类路径中。





这篇文章的主要内容

由于一般是根据 HTTP 协议在 Web 上传输 Atom 数据,因此要完全忽略潜在的安全隐患是不可能的。比如,联合内容会显示在多处而不是显示在其原始点(毕竟,这正是联合的意义所在),您如何证明其中一方未曾修改过数据?如果某些敏感数据只能由单一个体或组织获悉怎么办?当然,最明显的例子就是银行信息。您愿意通过原始的 HTTP feed 来接收银行信息吗?所有的敏感信息都存在这个问题,比如公司的内部信息。

这篇文章向大家介绍了如何使用数字签名和加密来解决此类问题。





快速回顾一下加密

还记得儿时与伙伴们分享的秘密暗号吗?您可以编制各种消息并对它们进行加密,您的伙伴可以使用暗号来解码这些消息。他还可以使用暗号创建您能够读懂的消息。这就是共享密钥(shared key)加密的一个例子,因为你们俩都有相同的暗号。

如今,这种方法能很好地防止消息内容被别人窥窃,稍后我将向大家介绍如何使用共享密钥加密来实现这一目的。

但是,共享密钥加密存在一个小问题。如果您接收到的一个加密消息告诉你使用雪球攻击女子俱乐部的房子,您如何才能分辨该消息确实是来自您的伙伴,而不是附近不怀好意的人在捉弄您呢?还有,如果您向伙伴发送了一条消息,如何才能保证只有他能够阅读该消息?

在成年人的世界里,可以通过使用公钥 — 私钥 加密来解决此类问题。它使用的并不是一个密钥,而是一个密钥对(key pair)。也就是说,一个人加密的消息只能由另一个人解密,反之亦然。

其中一个密钥是私有的,而另一个则是公有的,与其所有者相关。我们回到小孩的例子中,您的伙伴可以使用他的私钥来加密进攻计划。如果他的公钥可以成功地解密该计划,则您就能知道计划是由他发送的。当然,由于他的公钥是公有的,因此任何人都可以阅读该消息。另一方面,他可以使用您的公钥来加密消息,这就意味着只能使用您的私钥来阅读该消息。这种方法解决了安全问题,但是不能解决验证问题。

真实世界中需要结合两种技术来解决此类问题。比方说,可以对消息进行数字签名。这一过程能使您确定消息的发送者以及消息在传递途中是否被修改过。把这种技术与直接加密技术结合使用,所有的问题就迎刃而解了。

我们先从加密 Atom 条目开始。





加密 Atom 条目

考虑一个典型的 Atom 条目,比如那些可能位于博客中的条目(如清单 1 所示)。


清单 1. 一个样例条目
            <?xml version='1.0' encoding='utf-8'?>
            <entry xmlns="http://www.w3.org/2005/Atom">
            <id>urn:EncryptionExample/3263827</id>
            <author>
            <name>Nick Chase</name>
            </author>
            <title type="text">Apache Abdera eases Atom</title>
            <content type="text">
            Tired of making raw HTTP calls?  Now you can use a new
            package from Apache ...
            </content>
            <link href="http://incubator.apache.org/abdera/" />
            <updated>2007-03-20T12:43:26.687Z</updated>
            </entry>
            

这只是一个简单的 XML 文档,但是 Abdera 使您能够将它表示为一个对象(如清单 2 所示)。


清单 2. 条目作为对象
            import javax.crypto.KeyGenerator;
            import javax.crypto.SecretKey;
            import org.apache.abdera.Abdera;
            import org.apache.abdera.factory.Factory;
            import org.apache.abdera.model.*;
            import org.apache.abdera.security.*;
            public class EncryptionDemo {
            public static void main(String[] args) throws Exception {
            Abdera abdera = new Abdera();
            Factory factory = abdera.getFactory();
            Entry entry = factory.newEntry();
            entry.setId("urn:EncryptionExample/3263827");
            entry.addAuthor("Nick Chase");
            entry.setTitle("Apache Abdera eases Atom");
            entry.setContent("Tired of making raw HTTP calls?  Now "+
            "you can use a new package from Apache ...");
            entry.addLink("http://incubator.apache.org/abdera/");
            entry.setUpdated(new java.util.Date());
            entry.writeTo(System.out);
            }
            }
            

这一代码创建的 XML 如 清单 1 所示。首先,创建 Abdera 对象,它提供了所需的大部分功能。(安全函数大部分都在 AbderaSecurity class 中。)Abdera 对象提供了 Factory,它能创建条目或者其他对象。获得对象后,就可以设置它的属性。Entry 对象提供了一种简单的方式将自身置于命令行序列或者其他 OutputStream 序列中,非常方便。

把条目表示为对象的优点在于稍后能够以编程的方式对它进行加密(如清单 3 所示)。


清单 3. 加密条目
            ...
            entry.setUpdated(new java.util.Date());
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            keyGenerator.init(128);
            SecretKey secretKey = keyGenerator.generateKey();
            AbderaSecurity abderaSec = new AbderaSecurity(abdera);
            Encryption encryption = abderaSec.getEncryption();
            EncryptionOptions options = encryption.getDefaultEncryptionOptions();
            options.setDataEncryptionKey(secretKey);
            Document<Element> encryptedDoc =
            encryption.encrypt(entry.getDocument(), options);
            encryptedDoc.writeTo(System.out);
            }
            }
            

第一步创建用于加密消息的密钥。为此,我们需要一个 KeyGenerator 对象。您可以指定各种不同的加密算法,如数据加密标准(Data Encryption Standard,DES)和 RSA,不过 Java™ 1.5 环境的默认安装中包含了高级加密标准(Advanced Encryption Standard,AES)。此处我们设置了一个 128 位的密钥。生成密钥之后,便可以使用 AbderaSecurity 类获得一个 Encryption 对象并把刚创建的密钥提供给它。然后,我们便可以加密条目了。

加密后的结果类似于清单 4。


清单 4. 加密后的条目
            <?xml version='1.0' encoding='utf-8'?>
            <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
            Type="http://www.w3.org/2001/04/xmlenc#Element"><xenc:EncryptionMethod
            Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"
            /><xenc:CipherData><xenc:CipherValue>SWy9qLh7wwvAY2t/hhlC4kwGCuknc0Ml7aVm/B
            +kHZOkLb8Y7tQQ6pUvHBzmQTak075MTsjLgtWW
            lg/XH6RawbBUWiP3tLdHvI/S6rpgNyQFUKBv1CiG4mmFNktewu/FG5fZQMaqj3AtkQffyg4KLA+Q
            WXLD7Gbl4gvj9sUrmCBDDZs6U60aPNOManD6Bb0OppiFZdCvrvYQZ0yoLzISEnf46L+oEo56+FId
            5HHCilfvQb66DDhCHYl7NNR3ofF2P8Pg9eg1jWD4/ZGctCWuxWmQgPfdmJGJf+zsZwFCLfLmJWuL
            iARc16MrdMIFbKAgk61neyrco3fkQPhbTGvCK8wWOr2wHpzlAJAxrLX+TSpzqQ7jcWtX4VR07Sg0
            ymnMNvBCNWHUZeckswoTCUu78ujs/p51M8/csZSwg4ZUCcSf47wEm54rDJngaPPT31b8xeqVNxgS
            6eh/hwbcAiR/rf1LeeJz2KvcXI27aCmU5BT2wxxzRIHrpKiiExFhydCOFi+1WlOdzML6ghSjvxAo
            +gCd1b2zDX29t9AuvZ0I+zo=</xenc:CipherValue></xenc:CipherData>
            </xenc:EncryptedData>
            

您甚至能够为这些经过加密的条目创建一个 feed(如清单 5 所示)。


清单 5. 已加密条目的 feed
            ...
            Document<Element> encryptedDoc =
            encryption.encrypt(entry.getDocument(), options);
            encryptedDoc.writeTo(System.out);
            Entry entry2 = factory.newEntry();
            entry2.setId("urn:EncryptionExample/3263827");
            entry2.addAuthor("Nick Chase");
            entry2.setTitle("And you can use encryption, too");
            entry2.setContent("Abdera enables you to encrypt data.");
            entry2.addLink("http://incubator.apache.org/abdera/");
            entry2.setUpdated(new java.util.Date());
            Document<Element> encryptedDoc2 =
            encryption.encrypt(entry2.getDocument(), options);
            Feed feed = factory.newFeed();
            feed.addAuthor("Nick Chase");
            feed.addComment("These entries are encrypted using AES.");
            Entry encEntry = factory.newEntry();
            encEntry.setContent(encryptedDoc.getRoot());
            feed.addEntry(encEntry);
            Entry encEntry2 = factory.newEntry();
            encEntry2.addExtension(encryptedDoc2.getRoot());
            feed.addEntry(encEntry2);
            feed.writeTo(System.out);
            }
            }
            

在本例中,我们创建了另外一个条目,目的只是为了增加趣味性。然后,创建一个新 feed 并提供它的基本信息。接下来,创建一个空条目并将表示已加密条目的元素设置为它的内容。然后将填充后的条目添加到 feed。这个清单中还包含了一个把数据作为扩展(而不是内容)添加到条目的例子。

这表示了两种创建已加密数据的 feed 的方法。当然,您也可以使用相同的技术把 feed 作为一个整体进行加密。然而,在本例中,其结果类似于清单 6 所示(为更加清楚地显示,代码中添加了一些空格)。


清单 6. 已加密条目的 feed
            <feed xmlns="http://www.w3.org/2005/Atom">
            <author>
            <name>Nick Chase</name>
            </author>
            <!--These entries are encrypted using AES.-->
            <entry>
            <content type="application/xml">
            <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
            Type="http://www.w3.org/2001/04/xmlenc#Element">
            <xenc:EncryptionMethod
            Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
            <xenc:CipherData>
            <xenc:CipherValue>SLbTBADt8Dh2wS3LN7KLUyNCyzHFy4giwHwrmoEI4Z20M
            xrk+PSpU6ekldF9k2qPxYiE5zVAS5E2
            MxZOfV8M6CofAqP9/OeK16YBfP20+JyzEjdGChpQ3HqDo8lclfNOCTT0xmZY9+foGqmpEXyBquxU
            KDV9Yk7jq77TcGyrh50hbjrprg5O3+Htv2w+CSZNRr+ruB76p2wFT/gI1WHOqCg6CQCQ/EF+fMxY
            iYWLEVJ8wfrqjJytD4hy0xqSemMEedUo65qYl7rJuAsaABvKyiaspQNz/LEIeAkOpUC0aJqa1ERU
            ju/vRe/bVfC49cHsoUoYEOxcCF/KQxfC7wypeEJIyT99tDSgLMWKD1OpnI4g2JvIF9DqZFdnxpBH
            vAnlujs/2nj2JGyUxzQQb+e+YHcGlXeuTFZHlgwXwuBev8yxN842EJsGDtx++712hB+SRex+Rifu
            b0028qaRYETrXZX9hK7gmCEQGsbjXWYawKl0In/P/iMmVaoi3R3UKPJ8Dcdu/67Ukyr8AouquaTG
            cWGGcxtliaK67q/NeBL+fFk=</xenc:CipherValue>
            </xenc:CipherData>
            </xenc:EncryptedData>
            </content>
            </entry>
            <entry xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
            <xenc:EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element">
            <xenc:EncryptionMethod
            Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
            <xenc:CipherData>
            <xenc:CipherValue>JkgXKRwpjfcjqd8VweZuoMhtxK4wu1uJZLBLhRlDOz7t
            /+uHlxmjtzBYf0/izRo2NEO3ZYFhB9GF
            021N8HfnA0ZGh+2MS/FfQfqnSc0DsxzzxlKSEKFNIEcmpRzyrMVNE6kLVMicWgGJrm5t9ZcXXyZ4
            TRDKcFWGMjS3PEgd8KpCi0NYt8bAVxxNooGp7o8B7CiPZbgmjYYjo7WgP8l66auS7ciTZLoaEj3j
            jpmQyl0l1cGgAbCaBK2/hvfek7W6M1vkoLCCXZIr28cmeAfOT189i1+TrtZoOU8+xXYhHbPGlJG2
            5GAMyM89OpAy8psOrjEnxipF/04okKrULmmSeWA2QvqJsUAA4KtbmKQODLaac/eSJAp1eLikhBIW
            2GsfsVvmdO0yqNI96n8oY761yE6+1KEGpFohnIi7Zv5Xp7nI8jfXlFSnyiJaDiP/GxVC6MznnTdw
            iUqk8yxMak9fxLDBjRO6+VJHDPXZtPybnQ+3SJjKOxLUVFJmNP7sXO1P</xenc:CipherValue>
            </xenc:CipherData>
            </xenc:EncryptedData>
            </entry>
            </feed>
            

当然,加密后的内容必须要进行解密(如清单 7 所示)。


清单 7. 解密条目
            ...
            Document<Entry> decryptedEntry =
            encryption.decrypt(encryptedDoc, options);
            decryptedEntry.writeTo(System.out);
            ...
            

在本例中,我们使用与加密过程中相同的对象对内容进行解密。您应该可以看到结果为原始条目。

这个过程似乎很简单。但是如果要对条目签名该怎么做?





为数字签名做好准备

在使用数字签名之前,我们需要创建一个密钥对,一个公钥和一个私钥。有了这个密钥对,我们不仅能够对某个消息进行加密还能够为它创建一个证书。证书(certificate)就是一个包含了某个人(或实体)的公钥和其他信息(如姓名和序列号)的数字文件。在现实世界中,证书通常由一些受信任的机构(如 VerSign)或者某个内部实体进行签名,这样您便可以知道公钥是合法的。

在这些例子中,我们将使用自己签名的证书





生成密钥

幸运的是,创建密钥对所需的所有工具都是标准 Java 实现的一部分。具体来讲,我们需要 keytool 应用程序,可以在 JAVA_HOME/bin 中找到该程序。要创建一个 keystore,即保存密钥和初始密钥对的文件,请执行以下命令(如清单 8 所示)。


清单 8. 创建 keystore
            keytool -genkey -alias nick -keypass nickpass -keystore c:/sw/newkeystore.jks -storepass
            nickKeyStorePass
            

当然,您应该把一些参数替换为自己的值!

此命令将创建一个包含密钥对并且受密码保护的文件。为了简便起见,可以将 keystore 文件置于 Java 类所在的目录下面。





在条目中签名

有了密钥对之后,下一步便可以对条目进行签名了(如 清单 9 所示)。


清单 9. 对条目进行签名
            import java.io.ByteArrayInputStream;
            import java.io.ByteArrayOutputStream;
            import java.io.InputStream;
            import java.security.KeyStore;
            import java.security.PrivateKey;
            import java.security.cert.X509Certificate;
            import org.apache.abdera.Abdera;
            import org.apache.abdera.factory.Factory;
            import org.apache.abdera.model.Document;
            import org.apache.abdera.model.Entry;
            import org.apache.abdera.security.AbderaSecurity;
            import org.apache.abdera.security.Signature;
            import org.apache.abdera.security.SignatureOptions;
            import org.apache.abdera.model.Entry;
            public class DigitalSignatureDemo {
            public static void main(String[] args) throws Exception {
            Abdera abdera = new Abdera();
            Factory factory = abdera.getFactory();
            Entry entry = factory.newEntry();
            entry.setId("urn:EncryptionExample/3263827");
            entry.addAuthor("Nick Chase");
            entry.setTitle("Apache Abdera eases Atom");
            entry.setContent("Tired of making raw HTTP calls?  Now "+
            "you can use a new package from Apache ...");
            entry.addLink("http://incubator.apache.org/abdera/");
            entry.setUpdated(new java.util.Date());
            KeyStore keystore = KeyStore.getInstance("JKS");
            InputStream keyStream =
            DigitalSignatureDemo.class.getResourceAsStream("newkeystore.jks");
            keystore.load(keyStream, new String("nickKeyStorePass").toCharArray());
            PrivateKey privateKey = (PrivateKey)keystore.getKey(
            "nick", new String("nickpass").toCharArray());
            X509Certificate certificate = (X509Certificate)keystore.getCertificate("nick");
            AbderaSecurity abderaSec = new AbderaSecurity(abdera);
            Signature signature = abderaSec.newSignature();
            SignatureOptions options = signature.getDefaultSignatureOptions();
            options.setSigningKey(privateKey);
            options.setCertificate(certificate);
            entry = signature.sign(entry, options);
            entry.writeTo(System.out);
            }
            }
            

设计好条目之后,第一步需要把 KeyStore 作为对象进行加载,以便能从中检索数据。为此,需要在创建 keystore 时加载添加到其中的流和密码。(使用 storepass 参数。)

有了 keystore 之后,使用所指定的别名提取私钥。使用它来加密 digest(本质上讲是条目的一个散列)。这样就可以证明对条目进行签名的人是您。如果您的公钥能够解密条目,则使用您的私钥对它签名。当然,您需要提供公钥来进行验证。公钥是证书的一部分,接下来我们将以您的私钥为别名对它进行检索。

接下来,使用 AbderaSecurity 类获得一个 Signature 对象。我们将使用这个对象对条目进行签名,不过首先要给它提供私钥和证书。设置好这些选项后,就可以对条目进行签名了。

此过程向条目中添加数字签名,如清单 10 所示。


清单 10. 已签名的条目
            <entry xmlns="http://www.w3.org/2005/Atom">
            <id>urn:EncryptionExample/3263827</id>
            <author>
            <name>Nick Chase</name>
            </author>
            <title type="text">Apache Abdera eases Atom</title>
            <content type="text">Tired of making raw HTTP calls?  Now you can
            use a new package from Apache ...</content>
            <link href="http://incubator.apache.org/abdera/" />
            <updated>2007-03-21T13:23:18.812Z</updated>
            <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:SignatureMethod
            Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1" />
            <ds:Reference URI="">
            <ds:Transforms>
            <ds:Transform Algorithm=
            "http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
            <ds:Transform
            Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </ds:Transforms>
            <ds:DigestMethod
            Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <ds:DigestValue>DdQmuMjff9mkiNwmwwkex0LPHN8=</ds:DigestValue>
            </ds:Reference>
            </ds:SignedInfo>
            <ds:SignatureValue>DgTO6puBouHUxNWANLvNBM5XluU0Hx5xJP/E/16LC3QUv+2
            yersdqQ==</ds:SignatureValue>
            <ds:KeyInfo>
            <ds:X509Data>
            <ds:X509Certificate>
            MIIC6TCCAqYCBEYBMSYwCwYHKoZIzjgEAwUAMFoxDDAKBgNVBAYTA2FkZjENMAsGA1UECBMEYXNk
            ZjEOMAwGA1UEBxMFYXNkZmQxDTALBgNVBAoTBGFzZGYxDTALBgNVBAsTBGFzZGYxDTALBgNVBAMT
            BGFzZGYwHhcNMDcwMzIxMTMyMDM4WhcNMDcwNjE5MTMyMDM4WjBaMQwwCgYDVQQGEwNhZGYxDTAL
            BgNVBAgTBGFzZGYxDjAMBgNVBAcTBWFzZGZkMQ0wCwYDVQQKEwRhc2RmMQ0wCwYDVQQLEwRhc2Rm
            MQ0wCwYDVQQDEwRhc2RmMIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2
            EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7
            ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUA
            l2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdR
            WVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx
            +2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGALjc0JL8e3o3OVewD
            06EuudHR36srFq1cVVKV3gqZHluPjzw1LfJYo1vIFMr91oYMNSnlQz5HJRuC9Av8jpeYZGoxm/Vc
            5XHrICkGUFUfostU2ufGvc3k6z+pPGCSnyb2BhRnSZid1yl/MDnp5KQukXms/IGkpYqbrZcRtTs/
            s9UwCwYHKoZIzjgEAwUAAzAAMC0CFAj/LVbvicwcO168koFUSMWy/phjAhUAhYK5RadC0Cebmu+3
            wQbzPvQWZDA=
            </ds:X509Certificate>
            </ds:X509Data>
            </ds:KeyInfo>
            </ds:Signature>
            </entry>
            

注意,与加密的例子有所不同,原始的条目信息仍然会显示出来;签名只是被添加到其中。签名中包含了信息的处理方式,因此如果有人想要验证签名的话,则重复进行相同的步骤即可获得相同的结果。如果验证过程并未提供相同的结果,则说明消息是伪造的,或者消息在传递途中曾被修改。

同样,您可以把这些已签名的条目添加到 feed 中(如清单 11 所示)。


清单 11. 创建已签名条目的 feed
            ...
            entry = signature.sign(entry, options);
            //entry.writeTo(System.out);
            Feed feed = factory.newFeed();
            feed.addAuthor("Nick Chase");
            feed.addEntry(entry);
            feed.writeTo(System.out);
            }
            }
            

当然,如果无法验证签名,那么签名也就没什么用处了。





验证签名

验证签名是一个复杂的任务;不过值得高兴的是 Abdera 能够方便地处理它(如清单 12 所示)。


清单 12. 验证签名
            ...
            feed.addEntry(entry);
            Entry entryToCheck = feed.getEntries().get(0);
            if (signature.verify(entryToCheck, null)){
            System.out.print("The entry is valid.");
            } else {
            System.out.print("The entry has been tampered with!");
            }
            ...
            

此处您只是把条目作为对象进行检查,但是把它作为实际的 feed 发送之后会怎样呢?清单 13 显示了如何检查实际的 feed。


清单 13. 检查实际的 feed
            ...
            System.out.print("The entry has been tampered with!");
            }
            ByteArrayOutputStream feedOutput = new ByteArrayOutputStream();
            feed.writeTo(feedOutput);
            ByteArrayInputStream feedInput =
            new ByteArrayInputStream(feedOutput.toByteArray());
            Document<Feed> newFeedDoc = abdera.getParser().parse(feedInput);
            Feed newFeed = newFeedDoc.getRoot();
            Entry entryToCheckFromFeed = newFeed.getEntries().get(0);
            if (signature.verify(entryToCheckFromFeed, null)){
            System.out.println("The output entry is valid.");
            } else {
            System.out.println("The output entry has been tampered with!");
            }
            }
            }
            

如果您运行这个例子,您将看到 feed 和条目都是有效的。

注意,数字签名能检验经过签名的内容是否被修改过。这意味着添加或者移除一个空格将会使签名无效。由于这个原因,通常来说对整个 feed 进行签名是不合实际的,因为条目通常都是从上下文中取出的,并且在其他应用程序中使用。

结束语

在这篇文章中,我向大家介绍了对 Atom 数据进行数字签名和加密的一些相当简单的例子,数字签名能同时检验发送者和信息的完整性,加密用于防止未经授权的一方获得敏感信息。为了完成这些任务,我们使用了 Apache Abdera 项目,它能使我们方便地处理 Atom 数据。Abdera 中还包含了一些对象,通过这些对象能够轻松地集成客户端证书,以便在 servlet 级别自动加密 Atom 数据和完成更多功能。更多相关信息,请参阅 参考资料 中到 James Snell 信息的链接。






下载

描述名字大小下载方法
示例代码 x-atomencryption-source.zip 7KB HTTP

Search

导航

热门文章

最新文章

Powered By duduwolf's wiki 1.0

Copyright 1999-2007 duduwolf.com Some Rights Reserved.