在采用轻量级移动设备的推动下,基于REST的通信的采用日益广泛,因此需要保护这些通信。 当消息包含信息有效负载时,尤其如此,通常将其格式化为JavaScript Object Notation(JSON)文本。
本文演示了如何使用运行6.0.1.0版或更高版本固件的WebSphere DataPower设备来加密JSON有效负载,以便使用REST标准进行传输。 这样可以保护与传输方法(例如SSL)无关的消息私密性。 我们将演示以下方法:
整个有效负载使用PKCS#7标准进行加密。 使用共享密钥对选定的元素进行加密。 所选元素使用非对称密钥(证书和密钥)进行加密。传输的加密(或发送)端和传输的解密(或接收)端均在此进行了说明。
本文还演示了如何使用XQuery和JSONiq处理脚本来执行加密和解密。
您可以在传输的发送和接收端使用相同的多协议网关服务; 静态后端目标只需要调整。
本文使用加密密钥和证书。 为了不间断地完成这些说明,您必须首先创建加密密钥和证书对象。
请按照以下说明创建必要的密钥和证书对象:
在导航窗格的搜索栏中键入Ident 。 单击“ 加密标识凭证” 。 单击“ 添加”创建一个新的“身份凭证”对象。 在Name字段中输入Jason ,如图1所示。 单击加密密钥下的+按钮。 一个新的窗口打开。 在名称字段中输入Jason 。 上载加密密钥以完成此对象。 如果没有密钥,请使用设备上可用的加密工具来创建密钥。 点击应用 。 窗口关闭。 单击“身份证明”页面上“证书”下的+。 一个新的窗口打开。 在名称字段中输入Jason 。 上载加密证书对象以完成此对象。 如果没有密钥,请使用设备上可用的加密工具来创建证书。 点击应用 。 窗口关闭。 单击“ 应用”以完成“加密标识凭证”对象。这是本文使用的示例JSON文档:
{ "Name":"Cartoon Studios", "AccountID":"8458jf8757275234", "Social-no":"123-45-6789", "State":"MA" }通过执行本文中的步骤,可以确保“ Social-no”元素的值。
本文中创建的服务使用的目的地仅返回服务发送的内容,就像镜像一样。 要创建这样的目的地,请按照下列步骤操作:
在导航栏的搜索字段中键入HTTP 。 从出现的列表中选择HTTP服务 。 单击添加以创建新服务。 在名称字段中输入Mirror 。 将端口号更改为2049 。 将模式更改为echo 。 点击应用 。 点击保存配置 。完成此处描述的每个处理规则后,您可以通过向网关发送请求来测试新规则。
要测试加密规则,请将纯JSON有效负载request.jsn发送到网关。 例如,这是curl命令:
curl –data-binary @request.jsn http://dp_addr:3333/ssn要测试解密规则,首先需要创建一个加密的有效负载。 您可以通过捕获加密规则的输出来做到这一点。 这是使用curl的示例:
curl –data-binary @request.jsn http://dp_addr:3333/ssn > request-enc.jsn curl –data-binary @request-enc.jsn http://dp_addr:3333/dssn将应用程序域系统日志级别设置为“调试”,以捕获默认系统日志中的所有可能的调试条目。 为此,请单击控制面板上的“ 故障排除”图标。 在“ 日志记录”下 ,从“ 日志级别”下拉列表中选择“ 调试 ”。 然后单击“ 日志级别”按钮。
此处演示的所有方法都使用多协议网关服务来完成工作。 本节介绍此服务的配置(图3),除了“处理策略”。
在导航窗格上的搜索栏中键入Multi 。 从可能的条目列表中选择New MultiProtocol Gateway 。 输入或选择以下值: 名称: SecureJSON 预设后端网址: http://127.0.0.1:2049 : http://127.0.0.1:2049 : http://127.0.0.1:2049 响应类型:直通 请求类型:非XML此处详细介绍了将加密应用于JSON有效负载的三种方法。 您可能只想执行与要使用的方法有关的那些步骤。
请注意,网关配置使用非XML的请求类型来允许PKCS#7解密规则成功运行。 如果您不打算使用此规则,则可以将网关配置请求类型设置为JSON 。 这会使设备自动检查请求文档,以确保文档格式正确。 这对于探针也更有效。
当您向该规则提交样本请求文档时,您应该收到与以下内容相似的结果:
---BEGIN PKCS7----- MIIByQYJKoZIhvcNAQcDoIIBujCCAbYCAQAxgeAwgd0CAQAwRjA6MQswCQYDVQQG EwJVUzELMAkGA1UECBMCTUExDjAMBgNVBAcTBUtUb3duMQ4wDAYDVQQDEwVKYXNv bgIIBImBLUcGRo8wDQYJKoZIhvcNAQEBBQAEgYCHrd/qNEtgGZpXDK8yFLP65lO2 yRVtIst3E/hOqFy4Jt2YWtfsjLP2nuL27fEv3C+iLQSQo5leJCBaWF83xqUb4rMA I+1/8+T19ciEm5u7JhPAJ17G2Ypd1jqquXeVeJq6Mo1jYqTKjMt+2ir8ijhhuX6/ JzOIa+cAznBOD4+uaDCBzQYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBAgQQ2LCVsgxa 6alYZyGem0he2oCBoDbUr0nPULErHNfrk2twhBaPZzae3KUF07RYddamwBWBRkJe 7/Z4QU9WR8n/GoPe0vq6gsxHAaGqWCBoI0HCY+YTV6aF7ARlg5n2bVHKEx8lsH6G fxWwoKJu6j/BSmJCcoYaJNc5fATxr8mFKMJV1GcQg666hwzx143GkcAHmaclXu9w awpqndNhpKAukj6vxWUU8aAr8AehRRYaFXWoYf4= -----END PKCS7-----整个有效负载已加密。 将此结果保存在本地文件中,以提交解密此有效负载的规则,这将在下一部分中进行描述。
如果提交上面构造的用于加密JSON有效负载的规则的结果,则应该再次收到原始的纯文本JSON文档。
{ "Name":"Cartoon Studios", "AccountID":"8458jf8757275234", "Social-no":"123-45-6789", "State":"MA" }您必须创建一个共享密钥加密对象才能使用此方法。 如果尚未创建共享密钥,请按照“ 共享密钥”部分中的说明进行操作。
请按照以下步骤使用共享密钥来加密JSON有效内容的元素:
单击新规则。 将规则名称更改为SecureJSON_rule_ssencrypt. 将“ 规则方向”设置为“ 客户端到服务器” 。 双击突出显示的“ 匹配操作”图标。 点击+创建新的匹配 在名称字段中输入ssn 。 单击匹配规则选项卡。 点击添加 。 在URL匹配字段中输入 */ssn 。 点击应用 。 窗口关闭。 新规则输入到网格中,如图14所示。这是set-dp-var.xq文件的内容:
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; declare namespace dp = "http://www.datapower.com/extensions"; declare option jsoniq-version "0.4.42"; declare option output:method "json"; let $ssn := .("Social-no") let $dono := dp:set-variable("var://context/mine/myvar1", $ssn) let $myvar := dp:variable("var://context/mine/myvar1") return jn:object( for $key in jn:keys(.) let $val := if ($key = "Social-no") then $myvar else .($key) return { $key : $val } )该脚本从提交的消息中提取Social-no JSON元素的值,将其放在DataPower变量中,然后使用相同的变量再次输出消息。 此转换的输出并不重要; 最重要的是DataPower变量的设置。 在处理策略的下一步中使用此变量。
将另一个变换动作拖到“处理规则”上。 双击图标。 在“ 使用文档处理说明”下 ,选择“使用XSLT样式表转换” ,如图17所示。 上载string-crypto-var.xsl文件。 将输出上下文设置为NULL 。此样式表检索上一步中设置的DataPower变量的值,使用共享密钥对其进行加密,然后将结果放入DataPower变量中,如下所示:
<xsl:output method="xml"/> <xsl:template match="/"> <xsl:variable name="ssn"> <xsl:value-of select="dp:variable('var://context/mine/myvar1')" /> </xsl:variable> <xsl:variable name="result" select="dp:encrypt-string ('http://www.w3.org/2001/04/xmlenc#aes128-cbc', 'name:aes-128', $ssn)" /> <dp:set-variable name="'var://context/mine/myvar2'" value="$result" /> <output> <xsl:value-of select ="$result" /> </output> </xsl:template>再一次,此转换的输出并不重要。 变量值的设置很重要。
最后将“ 变换”动作拖到“处理规则”上。 双击图标。 在“ 使用文档处理说明”下 ,选择“使用处理控制文件转换”(如果已指定 ,如图18所示)。 输入语言应为JSON , 转换语言应为Xquery 。 单击“ 处理控制文件”下的“上载”按钮,然后上载use-dp-var.xq文件。 将输入设置为INPUT 。 将输出设置为OUTPUT 。 单击完成 。 窗口关闭。这是use-dp-var.xq文件的内容:
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; declare namespace dp = "http://www.datapower.com/extensions"; declare option jsoniq-version "0.4.42"; declare option output:method "json"; let $ssn := .("Social-no") let $myvar := dp:variable("var://context/mine/myvar2") return jn:object( for $key in jn:keys(.) let $val := if ($key = "Social-no") then $myvar else .($key) return { $key : $val } )该脚本输出原始消息,用加密的字段值代替原始值。
单击“ 应用策略” 。 如果这完成了所需的策略配置,请单击“ 关闭窗口”以关闭“处理策略”窗口。 然后在“网关”页面上单击“ 应用 ”。如果您通过此规则提交样本文档进行加密,则响应类似于以下内容:
{ "State":"MA", "AccountID":"8458jf8757275234", "Social-no":"RynTyS5R0hTDDT7e/3OfK0ItyC4rCxZQr8a3D2yITck=", "Name":"Cartoon Studios" }请按照以下步骤使用共享密钥来解密JSON有效负载的元素:
点击新建规则 。 将规则的名称更改为SecureJSON_rule_ssdecrypt 。 将“ 规则方向”设置为“ 客户端到服务器” 。 双击突出显示的“匹配操作”图标。 单击+创建一个新的匹配。 在Name字段中输入dssn ,如图19所示。 单击匹配规则选项卡。 点击添加 。 在URL Match字段中输入*/dssn 。 点击应用 。 窗口关闭。 新规则输入到网格中。这是set-dp-var.xq文件的内容:
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; declare namespace dp = "http://www.datapower.com/extensions"; declare option jsoniq-version "0.4.42"; declare option output:method "json"; let $ssn := .("Social-no") let $dono := dp:set-variable("var://context/mine/myvar1", $ssn) let $myvar := dp:variable("var://context/mine/myvar1") return jn:object( for $key in jn:keys(.) let $val := if ($key = "Social-no") then $myvar else .($key) return { $key : $val } )该脚本从提交的消息中提取Social-no JSON元素的值,将其放在DataPower变量中,然后使用相同的变量再次输出消息。 此转换的输出并不重要; 最重要的是DataPower变量的设置。 在处理策略的下一步中使用此变量。
将另一个变换动作拖到“处理规则”上。 双击图标。 在“ 使用文档处理说明”下 ,选择“使用XSLT样式表转换” ,如图22所示。 上载string-crypto-var-dec.xsl文件。 在输出上下文字段中输入 NULL 。此样式表检索上一步中设置的DataPower变量的值,使用共享的secred密钥对其解密,然后将结果放入DataPower变量中,如下所示:
<xsl:output method="xml"/> <xsl:template match="/"> <xsl:variable name="ssn"> <xsl:value-of select="dp:variable('var://context/mine/myvar1')" /> </xsl:variable> <xsl:variable name="result" select="dp:decrypt-data ('http://www.w3.org/2001/04/xmlenc#aes128-cbc', 'name:aes-128', $ssn)" /> <dp:set-variable name="'var://context/mine/myvar2'" value="$result" /> <output> <xsl:value-of select ="$result" /> </output> </xsl:template>再一次,此转换的输出并不重要。 变量值的设置很重要。
最后将“ 变换”动作拖到“处理规则”上。 双击图标。 在“ 使用文档处理说明”下 ,选择“使用处理控制文件转换”(如果指定的话) ,如图23所示。 输入语言应为JSON , 转换语言应为Xquery 。 在“ 处理控制文件”下 ,选择use-dp-var.xq文件。 将输入设置为INPUT 。 将输出设置为OUTPUT 。这是use-dp-var.xq文件的内容:
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; declare namespace dp = "http://www.datapower.com/extensions"; declare option jsoniq-version "0.4.42"; declare option output:method "json"; let $ssn := .("Social-no") let $myvar := dp:variable("var://context/mine/myvar2") return jn:object( for $key in jn:keys(.) let $val := if ($key = "Social-no") then $myvar else .($key) return { $key : $val } )该脚本输出原始消息,用未加密的字段值代替加密的值(图24)。
如果您提交使用共享密钥加密的有效负载,则将返回原始JSON文档。
{ "Name":"Cartoon Studios", "AccountID":"8458jf8757275234", "Social-no":"123-45-6789", "State":"MA" }此方法需要使用加密密钥和证书。 如果尚未创建密钥对象,请按照“ 密钥和证书对”部分中的说明进行操作。
点击新建规则 。 将规则的名称更改为SecureJSON_rule_asencrypt 。 将“ 规则方向”设置为“ 客户端到服务器” 。 双击突出显示的“ 匹配操作”图标。 单击+创建一个新的匹配。 在名称字段中输入ssna 。 单击匹配规则选项卡。 点击添加 。 在“ URL匹配”字段中输入 */ssna 。 点击应用 。 窗口关闭。 新规则将输入到网格中,如图25所示。这是extract-ssn-output.xq文件的内容:
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; declare namespace dp = "http://www.datapower.com/extensions"; declare option jsoniq-version "0.4.42"; declare option output:method "xml"; let $ssn := .("Social-no") return <output> {$ssn} </output>该脚本从JSON请求中提取Social-no元素的值,并将其包装为XML。 在这种情况下,脚本的输出很重要。 此XML输出在下一步操作中被加密。
为了在JSON消息中通过网络传输加密的值,必须对加密的数据块进行URL编码。 下一个动作将执行此任务。
将“ 变换动作” (图28)拖到“处理规则”上。 双击图标。 在“ 使用文档处理说明”下 ,选择“使用XSLT样式表转换” ,如图29所示。 上载urlencode.xsl文件。 将输出设置为NULL 。该样式表在PIPE上下文中检索Encrypted Data XML,对其进行URL编码以进行传输,然后将结果放入DataPower变量中。 输出并不重要。
<xsl:output method="xml"/> <xsl:template match="/"> <xsl:variable name="thisdoc"> <dp:serialize select="." /> </xsl:variable> <xsl:variable name="coded" select="dp:encode($thisdoc, 'url')" /> <dp:set-variable name="'var://context/mine/encrypted'" value="$coded" /> <output> <xsl:copy-of select="$coded" /> </output> </xsl:template> 最后将“ 变换”动作拖到“处理规则”上。 双击图标。 在“ 使用文档处理说明”下 ,选择“使用处理控制文件转换”(如果指定) 。 输入语言应为JSON , 转换语言应为Xquery 。 点击上传下的处理控制文件,并上传使用加密-var.xq文件。 将Input上下文设置为INPUT ,如图30所示。 将输出上下文设置为OUTPUT 。这是use-encrypted-var.xq文件的内容:
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; declare namespace dp = "http://www.datapower.com/extensions"; declare option jsoniq-version "0.4.42"; declare option output:method "json"; let $ssn := .("Social-no") let $myvar := dp:variable("var://context/mine/encrypted") return jn:object( for $key in jn:keys(.) let $val := if ($key = "Social-no") then $myvar else .($key) return { $key : $val } )该脚本输出原始消息,用加密的数据替换Social-no元素。
单击“ 应用策略” 。 如果这完成了所需的策略配置,请单击“ 关闭窗口”以关闭“处理策略”窗口。 然后在“网关”页面上单击“ 应用 ”。如果使用此规则将示例JSON文档提交到网关,则将返回部分加密的文档,如下所示:
{ "State":"MA", "AccountID":"8458jf8757275234", "Social-no":"%3C%3Fxml+version%3D%221.0%22+encoding%3D%22UTF-8%22%3F%3E%0A%3Cxenc %3AEncryptedData+Type%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmlenc%23Element%22+xmlns%3Axenc %3D%22http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmlenc%23%22%3E%3Cxenc%3AEncryptionMethod+Algorithm %3D%22http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmlenc%23tripledes-cbc%22%2F%3E%3Cdsig%3AKeyInfo+xmlns %3Adsig%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23%22%3E%3Cxenc%3AEncryptedKey+Recipient %3D%22name%3AJason%22%3E%3Cxenc%3AEncryptionMethod+Algorithm%3D%22http%3A%2F%2Fwww.w3.org%2F2001 %2F04%2Fxmlenc%23rsa-1_5%22%2F%3E%3Cdsig%3AKeyInfo%3E%3Cdsig%3AKeyName%3EJason%3C%2Fdsig%3AKeyName %3E%3C%2Fdsig%3AKeyInfo%3E%3Cxenc%3ACipherData%3E%3Cxenc%3ACipherValue%3EYCbZxpgATnTDySkvoJPJEP %2BQfqo323mNnozEUxarFohagST06iY4R%2FuwFPsnQEAIVQbmQqxnvUJ3qA63DtBg4GXAEvAPdgyl1947qU8qtDJzTzLixEM7BE7H %2B7ITTDbPiUm6ZslhYe4hvhWYa441AqaA8tdMCL2e5MhcWliTK4Y%3D%3C%2Fxenc%3ACipherValue%3E%3C%2Fxenc %3ACipherData%3E%3C%2Fxenc%3AEncryptedKey%3E%3C%2Fdsig%3AKeyInfo%3E%3Cxenc%3ACipherData%3E%3Cxenc %3ACipherValue%3EhN7LmbrYWJuEM3hFQYjvXua2p%2FtjnQsgto6vQ%2F1HgzEd5SmjLlH5PgL%2FYCop1MSJPiWI9bO %2BYpl811Hi63gO9M3uf7H73%2F8CLTbKjQWkPvuTX0CkGP7LtHMgPGxLvHZxJpusGBN5f6A%3D%3C%2Fxenc%3ACipherValue %3E%3C%2Fxenc%3ACipherData%3E%3C%2Fxenc%3AEncryptedData%3E", "Name":"Cartoon Studios" }这是set-dpvar-encrypted.xq文件的内容:
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; declare namespace dp = "http://www.datapower.com/extensions"; declare option jsoniq-version "0.4.42"; declare option output:method "xml"; let $ssn := .("Social-no") let $dono := dp:set-variable("var://context/mine/encrypted", $ssn) return <output> {$ssn} </output>在这种情况下,输出并不重要; 设置变量很重要。 下一个动作将使用它。
将“ 变换”动作拖到“处理规则”上。 双击图标。 在“ 使用文档处理说明”下 ,选择“使用XSLT样式表转换” ,如图35所示。 上载urldecode-var.xsl文件。 在“ 输出上下文”字段中输入 posted的类型。此样式表的输出很重要。 I由其后的Decrypt操作使用。
这是样式表:
<xsl:output method="xml"/> <xsl:template match="/"> <xsl:variable name="ssn"> <xsl:value-of select="dp:variable('var://context/mine/encrypted')" /> </xsl:variable> <xsl:variable name="decode"> <xsl:value-of select="dp:decode($ssn, 'url')" /> </xsl:variable> <xsl:copy-of select="dp:parse($decode)" /> </xsl:template> 将解密图标拖到处理行上。 双击图标。 一个新的窗口打开。 从可能的Input上下文中选择发布 ,如图36所示。 将消息类型设置为整个文档 。 使用解密密钥 Jason 。 在输出上下文字段中输入 outdata 。解密后的数据现在位于outdata上下文中。 下一步操作将使用此输入,并将数据放在DataPower变量中,以备后用。
将“ 变换”动作拖到“处理规则”上。 双击图标。 从可能的Input上下文列表中选择outdata ,如图37所示。 在“ 使用文档处理说明”下 ,选择“使用XSLT样式表转换” 。 上载make-decoded-var.xsl文件。 在输出上下文中输入relegate 。此样式表的输出并不重要; 设置变量很重要。
这是样式表:
<xsl:output method="text"/> <xsl:template match="/"> <dp:set-variable name="'var://context/mine/decoded'" value="/output/text()" /> <xsl:copy-of select="/output/text()" /> </xsl:template> 最后将“ 变换”动作拖到“处理规则”上。 双击图标。 从可能的Input上下文列表中选择INPUT ,如图39所示。 在“ 使用文档处理说明”下 ,选择“使用处理控制文件转换”(如果指定) 。 输入语言应为JSON , 转换语言应为Xquery 。 单击“ 处理控制文件”下的“上载”按钮,然后上载use-decoded-var.xq文件。 从可能的输出上下文列表中选择输出 。这是use-decoded-var.xq文件的内容:
let $ssn := .("Social-no") let $myvar := dp:variable("var://context/mine/decoded") cast as xs:string return jn:object( for $key in jn:keys(.) let $val := if ($key = "Social-no") then $myvar else .($key) return { $key : $val } )该文件输出未加密的消息。 如果将使用非对称密钥加密的有效负载提交给网关,则会返回原始消息。
{ "Name":"Cartoon Studios", "AccountID":"8458jf8757275234", "Social-no":"123-45-6789", "State":"MA" }本文构建的处理策略为您提供了三种不同的方法来保护在基于REST的体系结构中传输的JSON有效负载。 无论传输协议如何,这都会保留有效负载的私密性。 您学习了如何加密整个有效负载或仅选择元素。 对于给定的用例,您可能只需要使用一种方法。 但是,这为您提供了仅创建方案所需的安全处理的策略或基础。
图40显示了处理策略以及本文中描述的所有规则。
翻译自: https://www.ibm.com/developerworks/websphere/library/techarticles/1401_shute/1401_shute.html
相关资源:WebSphere7.0集群及负载均衡搭建手册