寻找用于加密机密数据的方法
通常,在需要发送一些敏感数据时,可以通过两种方法来保护通信。一种是使用安全套接字层 (SSL),它可以保护整个通信的安全。但是,仅基于 HTTP 的安全是不够的。HTTP 及其安全机制仅能解决点到点的安全问题。当消息可能跨多个跃点传递时,您必须使用更复杂的解决方案,该解决方案应能够在多点消息路径中保持一个安全上下文。共有两种可能的方法可以帮助解决此问题:
*WS-Security
*XML 标准加密
这两个解决方案都提供了消息级别的安全性,将安全功能合并到 SOAP 消息中并作用于应用层,因此保证了端到端的安全。WS-Security 加密方法是加密 SOAP 消息的 Web 服务安全标准,而 XML 加密方法是可用于加密 XML 消息甚至其一部分的标准。为更好地理解这两种加密之间的不同,我们根据将要解决的场景比较一下这两种方法。
假定通过中央预约系统传输的日程包含了关于预约时段的日期的所有信息,这些信息包装在 sdoWrapper 服务数据对象 (xmlString) 中,并用类似于 XML 的格式表示,如清单 1 所示。
清单 1. SOAP 消息
<soapenv:Envelope
xmlns:soapenv="http://schemas.XMLsoap.org/soap/envelope/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header />
<soapenv:Body>
<p374:sendUpdatedAgenda xmlns:p374="http://Asynch_Library/AsynchResSystemExport">
<sdoWrapper>
<xmlString />someConfidentialContent </xmlString >
<sdoWrapper/>
<serviceProviderId >ASL1<serviceProviderId >
</p374:sendUpdatedAgenda >
</soapenv:Body>
</soapenv:Envelope>
由于此消息是机密消息,因此需要一些信息才能确定要将消息发送到的服务提供者;已经为此目的添加了 serviceProviderId。为保护此数据,我们决定加密整个 sdoWrapper 服务数据对象。如果需要向 sdoWrapper 对象添加更多的敏感信息,此选项可以保证提供较好的灵活性。不过,请记住,使用 XPath 表达式还可以仅加密 XML 消息的服务数据对象的某一部分。
XML 标准加密和 WS-Encryption 都遵循两步加密数据的方法:
1.使用受信方证书中包含的公钥生成共享密钥(非对称加密)。
2.使用以前生成的密钥加密 SOAP 消息中的敏感数据(对称加密)。
这样,您使用非对称加密仅生成和保护了要共享的密钥,而使用对称加密来执行数据加密,因此提高了性能。当收到加密的消息时,受信任方使用其私钥解密会话密钥,然后使用它解密消息。此机制确保了只有受信方可以执行消息的解密,而此受信方只能是拥有正确私钥的一方。在清单 2 中,您可以看到将 WS-Encryption 应用于上文描述的 SOAP 消息以加密服务数据对象的结果。
清单 2. WS-Encryption
<?xml version="1.0" encoding="UTF-8" ?>
-<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soapenv="http://schemas.XMLsoap.org/soap/envelope/"
-<soapenv:Header>
-<wsse:Security soapenv:mustUnderstand="1"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/
oasis-200401-wss-wssecuritt-secext-1.0.xsd">
<xenc:EncryptedKey xmls:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptedMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
-<dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
-<wsse:SecurityTokenReference>|
<wsse:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/2004/01/oasis
-2004-wss-x509-token-profile-1.0#x509v3SubjectKeyIdentifier"EncodingType=
"http://docs.oasis-open.org/wss/2004/01/oasis-2004-wss-soa-message-security
-1.0#Base64Binary">EOStvn5dTJTROjuM2rn9Ov9dQlQ=
</wsse:KeyIdentifier>
</dsig:KeyInfo>
-<xenc:ChiperData xmls:dsig="http://www.w3.org/2000/00/xmldsigc#">
<xenc:ChiperValue >AIWDQKgc09cBkwjXNPQ8NleT5ZMvuLqQJZUijEXsvvBzhclT
czzDbFGTh67n9NMlpoiu)0p)xcfDATfgJuWQ+KKLN7DsErt543lkvuHTP+lllCV=OPPmhjkoik
jRT4589JCdxzT432LLp098B00 </xenc:ChiperValue>
</xenc:ChiperData>
</xenc:EncryptedKey>
</wsse:Security>
</soapenv:Header>
-<soapenv:Body>
-<q0:sendUpdatedAgenda >
-<xenc:EncryptedData Id="G248054f8-1bD" Type="http://www.w3.org/2001/04
/xmlenc#Element"xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/
xmlenc#tripledes-cbc"/>
-<xenc:ChiperData >
<xenc:ChiperValue >DDY/AI0WDQppKgcyc09cBkwjXNPQ8NleT5234ZMvudcLqQJ4
cDFGTh67+sTr23KYXAsw0M+kc2opDsErt543lkvuHTP+lllCV=OPPmhjkoikZMvudcLqQJ4
ZUijE1111+XsvvBz3wh34hedcls2FTss$+sTr23KYXAsw0M+kzPSRt4ZMvud+sTr23KYXAs
jRT4589JCdxzT432LLp098B00 </xenc:ChiperValue>
</xenc:ChiperData>
</xenc:EncryptedData>
<serviceProviderId >ASL1<serviceProviderId >
</q0:sendUpdatedAgenda >
</soapenv:Body>
</soapenv:Envelope>
注意,通过使用 WS-Encryption,与生成的共享密钥相关的所有信息都包含在消息头中,而加密的数据则包含在消息正文中。对于生成的密钥而言,此结构的根元素是 EncryptedKey,它包含 dsig:KeyInfo 和 dsig:KeyValue 元素,二者都属于同一 XML 数字签名 (dsig:) 命名空间。而加密的数据则包含在 EncryptedData 元素中,该元素属于 XML 加密 (xenc:) 命名空间。EncryptedKey 和 EncryptedData 部分分别包含有关用于非对称加密密钥 (rsa_15) 和对称加密数据 (tripledes-cbc) 的算法的详细信息。CipherValue 元素则包含密钥和敏感数据的加密值。使用标准 XML 加密方法来加密 sdoWrapper 服务数据对象将生成如清单 3 所示的结果。
清单 3. 标准加密
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenv="http://schemas.XMLsoap.org/soap/envelope/"
xmlns:q0="http://Asynch_Library/AsynchResSystemExport">
-<soapenv:Body>
-<q0:sendUpdatedAgenda >
<xenc:EncryptedData Type="http://www.w3.org/2001/04/xmlenc#triplesdes-cbc"/>
-<dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
<xenc:EncryptedMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"
-<xenc:ChiperData>
<xenc:ChiperValue >AIWDQKgc09cBkwjXNPQ8NleT5ZMvuLqQJZUijEXsvvBzhclT
czzDbFGTh67n9NMlpoiu)0p)xcfDATfgJuWQ+KKLN7DsErt543lkvuHTP+lllCV=OPPmhjkoik
jRT4589JCdxzT432LLp098B00 </xenc:ChiperValue>
</xenc:ChiperData>
</xenc:EncryptedKey >
</dsig:KeyInfo >
-<xenc:ChiperData xmls:dsig="http://www.w3.org/2000/00/xmldsigc#">
<xenc:ChiperValue >AIWDQKgc09cBkwjXNPQ8NleT5ZMvuLqQJZUijEXsvvBzhclT
czzDbFGTh67n9NMlpoiu)0p)xcfDATfgJuWQ+KKLN7DsErt543lkvuHTP+lllCV=OPPmhjkoik
jRT4589JCdxzT432LLp098B00 </xenc:ChiperValue>
</xenc:ChiperData>
</xenc:EncryptedData>
<serviceProviderId >ASL1<serviceProviderId >
</q0:sendUpdatedAgenda >
</soapenv:Body>
</soapenv:Envelope>
这里需要重点强调的一点是,这与直接使用 WS-Encryption 加密方法不同。通过使用标准 XML 加密,所有与安全相关的信息,包括加密密钥和加密的数据都包含在 SOAP 消息的正文中(加密的密钥不再嵌入 SOAP 头中)。而且,对于以类似于 XML 格式编写的 SOAP 消息,您始终可以使用 XML 标准加密方法来加密 SOAP 消息的正文或正文的某部分。当您需要在 SOAP 消息的正文中传输与安全相关的所有信息(如用于执行加密的算法、加密的共享密钥、加密的数据等)时,此方法特别有用。
在本例中,SOAP 消息(如上所述)在被加密后转到执行协议切换的 ESB,然后将这些消息路由到一些 Java™ Message Service (JMS) 客户端,所有客户端都在同一主题上注册。加密可以保证有关某个主题的数据机密性,原因是只有拥有正确私钥的服务提供者才能正确执行解密,因此也能读懂该数据。在此场景中,采用 WS-Encryption 方法加密数据显然不是一个好选择。事实上,对于 SOAP 消息头中提供的与密钥相关的信息,该信息将在消息转换为 JMS 格式时丢失。不过,使用标准 XML 加密,安全信息将不会丢失,这是因为嵌入消息的正文将意味着它将得到保留并只需转换为 JMS 负载。JMS 客户端然后将该消息转换为 XML 文本格式,并使用标准 API 对其解密。由于必须加密这些 SOAP 消息,我们决定利用 WebSphere DataPower SOA Appliances 的功能来执行标准 XML 加密,以避免在中央预约系统上加密和解密 SOAP 消息的编程负担。