动态Paypal按钮加密

17

我正在使用PHP和MySQL设计一个订单网站。在最后阶段,用户将获得Paypal按钮以支付他所下的订单。因此,商品名称和价值是变量。

这些变量的存在导致我不能使用来自Paypal的加密按钮。我必须使用非加密按钮或在向用户显示之前加密它。

出于安全原因,我希望对其进行加密。我想知道如何在我的服务器上进行加密。

6个回答

33

您需要做的事情相当复杂,首先介绍一下,PayPal加密按钮具有以下布局:

    <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----MIIIEQYJKo...Encrypted stuff...IF5ioje8JH0LAA+5U7P+tabAMOL37k=-----END PKCS7-----">
<input type="image" src="https://www.paypalobjects.com/es_XC/MX/i/btn/btn_buynowCC_LG.gif" border="0" name="submit" alt="PayPal, la forma más segura y rápida de pagar en línea.">
<img alt="" border="0" src="https://www.paypalobjects.com/es_XC/i/scr/pixel.gif" width="1" height="1">
    </form>

cmd字段指示加密的“立即购买”按钮(请检查要创建的按钮的值),而encrypted字段是以下布局中按钮的实际内容:

    cert_id=ZQCMJTZS27U4F
    cmd=_xclick
    business=contact@mybiz.com
    item_name=Handheld Computer
    item_number=1234
    custom=sc-id-789
    amount=500.00
    currency_code=USD
    tax=41.25
    shipping=20.00
    no_note=1
    cancel_return=http://www.company.com/cancel.htm 
注意,以下内容采用的是键值对格式,并且为了完整的参考请查看此处:https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_Appx_websitestandard_htmlvariables
理论上,要获取加密字段,则需要使用您的证书(x509 证书)和私钥来签署这些值,然后使用 PayPal 的公共证书加密此已签署的消息。
实际操作中,您可以(需要)使用以下两个 PHP 函数(OpenSSL 扩展的一部分):openssl_pkcs7_sign 和 openssl_pkcs7_encrypt。
我发现设置这个最后部分非常棘手,所以我建议您下载 PayPal 的 PHP SDK,这里有可用的https://www.x.com/community/ppx/sdks#WPST 和直接下载链接 https://cms.paypal.com/cms_content/US/en_US/files/developer/PP_PHP_WPS_Toolkit.zip,该 SDK 包含 EWPServices 类,其中包含 encryptButton 方法,可以轻松地为您提供加密的按钮;如果您想查看细节,请参考 PPCrypto 类,该类提供了 signAndEncrypt 方法, 仅提供所需字段的加密字符串,并显示加密按钮的过程。
顺便说一下,如果您不知道如何获取证书和私钥(和/或 PayPal 的证书),请在此处查看:https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_encryptedwebpayments#id08A3I0N30Y4

2
顺便说一下,如果您不知道如何获取证书和私钥(以及/或Paypal的证书),请查看此处:https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_encryptedwebpayments#id08A3I0N30Y4 - Rafael
6
最佳解决方案。应标记为答案。实际上讲述了如何动态加密 PayPal 按钮。 - Stephen Smith
1
@GuyLowe 数据使用PayPal的公钥进行加密,他们可以轻松解密,因为他们持有相应的私钥。 - Rafael
1
@GuyLowe 数据使用您的私钥进行签名,然后加密。当PayPal解密它时,他们会得到按钮数据的明文以及来自您的私钥的签名,以确保数据没有被篡改。他们使用您上传的公共证书来验证签名,并且可以通过业务字段知道这是您的数据,通过cert_id字段使用正确的证书。 - Rafael
1
@GuyLowe,如果你对细节感兴趣,我建议你阅读有关公钥加密的内容。 - Rafael
显示剩余8条评论

4

从你的帖子中,你似乎对加密的含义和使用场景非常困惑。威胁模型是什么?(即它如何被破坏)。

你绝不能期望Paypal会始终处理你发送给客户浏览器的订单。你必须检查Paypal已经处理了什么。

订单离开你的站点后,你可以更好地确保其完整性,例如通过在发送给Paypal的订单号(和盐!)中添加订单的哈希值。这应该允许你验证订单,而不需要参考PLU/存储订单(只要处理来自paypal的返回的脚本知道盐值)。


太棒了。当我发布这个被关闭的问题(http://stackoverflow.com/q/14489512/105539)时,我没有想到这一点。所以只需使用“custom”变量,并在IPN过程中添加像md5($sSalt . $sProduct . $sPrice)这样的内容,确保它们对齐即可。 - Volomike
2
这不是提问者正在寻找的解决方案。他可能已经在做这个了。加密按钮的原因是为了通过使篡改支付变得非常困难,从而在第一时间大大降低威胁。 - Stephen Smith

1

我开发了一个PHP集成工具包,用于PayPal网站支付标准

这里提到的所有问题都由辅助类处理。一些基本配置提供了简单的设置。例如,所有加密变量(您的私钥、公共证书等)都可以进行配置。本文详细介绍了如何使用这些类。

PS:只有IPN确认由辅助类实现。


1
链接已失效,请修复或删除。 - Guy Lowe

1
也许你可以尝试将这些变量放入一个带有唯一ID的临时表中,然后使用该ID来控制按钮。每当客户点击PayPal按钮时,从表中查询变量。我只是希望我理解了你的陈述 xD

1

你唯一能够做到这一点的方法是每次动态查询 PayPal 来加密按钮。

然而,这种方法并不高效,我认为最好使用 PayPal IPN。网上有许多关于如何使用它的示例和类。


我认为IPN可能是解决这个问题的方法。要么就是使用自定义按钮。我会进一步研究它... - Phillip Senn
2
注意:IPN 检查支付后,您仍然会遇到被篡改的付款情况。尽管他们得不到产品,但似乎有点混乱,因为您偶尔会收到被篡改的付款。 - Stephen Smith

0

任何人都可以使用您的PayPal电子邮件地址向您发送虚假发票,要求错误价格的产品名称吗?如果他们要费心更改您的js / html代码以向您发送虚假发票...他们可以编写自己的(只需提交表单到'paypal.com/cgi-bin/webscr')。您真正需要的只是卖家的PayPal电子邮件,对吧?

那么为什么要费心加密按钮呢?


1
任何人都可以在浏览器的付款页面上按下“F12”键,然后根据需要编辑HTML。降低金额是一个明显的问题,除非您在发货之前检查匹配(PayPal建议),否则他们会得到更便宜的价格。即使您发现了差异,您也必须与客户争论并可能退款。使用加密按钮,所有重要信息都无法被篡改,在您的PayPal首选项中,您只能允许加密按钮,从而防止出现这种情况。 - Patanjali

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接