我有一个在浏览器中签署文本字符串的Javascript。它使用Internet Explorer下的CAPICOM和Mozilla浏览器下的window.crypto。签名过程完成后,我收到了BASE64编码的签名。
使用HTTPS,我将签名和文本字符串上载到具有PHP应用程序的Web服务器。从SSL(HTTPS),我收到用户的证书。从该证书中,我可以提取用户的公钥。
现在,我想根据签名的文本字符串以及用户的证书和公钥来验证签名。我尝试使用openssl_verify PHP函数没有成功。
我总是收到一个错误:
error:0408D077:rsa routines:FIPS_RSA_VERIFY:wrong signature length
不幸的是我无法验证签名?我无法提供演示或示例,因为它目前仅在本地网络中。
最佳答案
好的,最后我找到了解决方法。
window.crypto
生成签名。有关更多信息,请阅读this 两者-
window.crypto
和CAPICOM都没有很好地记录在Web使用中(CAPICOM不仅用于Web!)现在的问题:
openssl_verify()
函数也没有得到很好的说明,并且始终返回零-签名无效。 那么解决方法是什么:
signText()
函数需要第三个参数,该参数必须是受信任的证书颁发机构名称。首先,我希望这必须是客户证书发行者的CN。但实际上并非如此。必须使用逗号分隔所有发行者字符串,例如:"C=Country,ST=State,L=Location,O=Organization,CN=CommonName,STREET=Address"
不幸的是,该字符串与openssl的发行者字符串(看起来像issuer=/streetAddress=Address/CN=CommonName/O=Organization/L=Location/ST=State/C=Country
)略有不同。如果有人使用Linux下的Firefox,检查此字符串的格式是否相同将非常有趣。我不知道如何在单个字符串中分隔更多CA名称。 现在。我的源代码如下所示:
window.crypto
的CAPICOM生成的(我从Web浏览器收到一个附加参数,如何生成签名)如果使用了CAPICOM,我将像这样转换源数据:$_POST['source'] = iconv('UTF-8', 'UTF-16LE', $_POST['source'])
"-----BEGIN PKCS7-----\n".$_POST['signature']."\n-----END PKSC7-----"
注意,页眉和页脚必须位于单独的行上。行分隔符只能是\r\n(ASCII#13#10)的\n(ASCII#10)而不是\r(ASCII#13)。 smime
-使用CMD工具-verify
-做一个验证-in filepath
-在步骤4中创建的签名文件的路径-inform PEM
-签名的范围是具有页眉和页脚-binary
-防止源代码从二进制转换为文本-content filepath
-在步骤3中创建的源文件的路径-CAfile filepath
-在步骤5中创建的受信任CA根证书文件的路径因此,最终命令如下所示:
openssl smime -verify -in file.pem -inform PEM -binary -content source.txt -CAfile root.pem
Verification successful
开头-签名正常Verification failure
开头-签名不正确以上对我有用。不幸的是,openssl,CAPICOM和
window.crypto
非常棘手,并且总是有可能发生问题。希望这会帮助到别人。此致
关于php - 如何使用PHP从浏览器检查数字签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12617150/