内容


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

当 Abdera 遇到 Java 加密技术

Comments

准备工作

阅读本文需对 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 信息的链接。


下载资源


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=XML, Java technology
ArticleID=236404
ArticleTitle=对 Atom 进行签名,加密和解密
publish-date=06252007