xishizhaohua 2019-06-26
RSA非对称加密,在网络鉴权中使用很多。本人也是在PHP与C++交互鉴权时出现问题,在解决问题过程中发现,网上对相关问题的描述很少,所在这里记录下,希望对遇到相似问题的朋友有所帮助。
问题情景:
由于项目需求,需要PHP写接口提供给C++调用,在接口返回数据之前,需要对访问者进行鉴权已增加数据访问安全性。
针对需求,我们采用的是两次握手完成鉴权。
第一次访问接口不带参数,接口返回token和RSA公钥(公钥用base64加密,方便传输)。
第二次访问接口,客户端需使用返回公钥加密访问参数,之后将加密后的参数和token一起发送给服务端进行验证。服务端收到访问数据后,对加密参数用私钥解密,检查参数是否符合要求,完成鉴权过程。
我们的问题出现在第二次访问时,发送过来的加密参数,无法通过私钥解密。
注:公钥和私钥有PHP生成,使用这对公钥私钥可以在PHP端完成加解密,使用相同的公钥私钥也可以在C++端完成加解密,但两者互通就会出现问题。
解决过程:
直接上正确思路,我们使用相同公钥对相同参数进行加密后发现,两者长度相差很大,于是判定应该是加密后两者的编码方式不同,据我了解RSA加密后C++端应该是输出十六进制的密文,而PHP使用openssl_public_encrypt 公钥加密后的密文应该是ASCII码字符串,两者长度相差很大。
根据以上判断,C++发送给PHP的是十六进制密文,而使用openssl_private_decrypt解密需要的是ASCII码字符串,当然解不出来了。既然知道问题所在,那我们把十六进制的密文转换成ASCII码字符串不就可以解决问题了,于是在PHP端使用pack("H*", param) 转码密文,之后果然顺利解密。
关于pack函数的详细介绍可以看OSC上一位朋友的博客,链接在此
简单总结:
1.用pack(“H*”)
2.php base64加密公钥传递给C++
3.C++ 用公钥加密信息 post传递给PHP解密