老铁,还得麻烦看看,uniapp公钥加密,服务端[php]对应私钥解密,无法解密
byphp-com opened this issue · comments
Addy commented
uniapp端使用私钥加密,服务端[php]使用对应公钥解密,正常
服务端[php]使用私钥加密,uniapp端公钥钥解密,也正常
/**
* 字符串RSA加密
* @param uncrypted
* @param keys
* @param digest base64\buffer|binary|hex
* @returns {*}
*/
rsaEncrypt(uncrypted, keys, digest = 'base64') {
let rsa = new Signature.RSA(); // RSA对象
// 使用私钥加密
rsa.setPrivateKey(keys.privateKey);
let encrypted = rsa.keys.encryptPrivate(uncrypted, 'base64');
console.log('encrypted', encrypted);
return encrypted;
}
/**
* 字符串RSA解密
* @param encrypted
* @param keys
*/
rsaDecrypt(encrypted, keys) {
let rsa = new Signature.RSA(); // RSA对象
// 使用公钥解密
rsa.setPublicKey(keys.publicKey);
let decrypted = rsa.keys.decryptPublic(encrypted, 'utf8');
// console.log('decrypted', decrypted);
return decrypted;
}
但是如果:
uniapp端使用公钥加密,服务端[php]使用对应私钥解密,无法解密
服务端[php]使用公钥加密,uniapp端使用私钥解密,也无法解密
/**
* 字符串RSA加密
* @param uncrypted
* @param keys
* @param digest base64\buffer|binary|hex
* @returns {*}
*/
rsaEncrypt(uncrypted, keys, digest = 'base64') {
let rsa = new Signature.RSA(); // RSA对象
//使用公钥加密,对方使用私钥解密
rsa.setPublicKey(keys.publicKey);
let encrypted = rsa.encrypt(uncrypted, digest);
console.log('uncrypted', rsa, uncrypted, keys.publicKey, digest);
return encrypted;
}
/**
* 字符串RSA解密
* @param encrypted
* @param keys
*/
rsaDecrypt(encrypted, keys) {
let rsa = new Signature.RSA(); // RSA对象
// 使用私钥解密
rsa.setPrivateKey(keys.privateKey);
let decrypted = rsa.decrypt(encrypted, 'utf8');
return decrypted;
}
这是我服务端的代码
/**
* 私钥加密
*
* @param $data
* @param $rsaPrivateKey
*
* @return string
*/
public static function privateKeyEncode($data, $rsaPrivateKey)
{
$encrypted = '';
$private_key = openssl_pkey_get_private($rsaPrivateKey);
if ($private_key)
openssl_private_encrypt($data, $encrypted, $private_key); //私钥加密
return base64_encode($encrypted);
}
/**
* 公钥加密
*
* @param $data
* @param $rsaPublicKey
*
* @return string
*/
public static function publicKeyEncode($data, $rsaPublicKey)
{
$encrypted = '';
$public_key = openssl_pkey_get_public($rsaPublicKey);
if ($public_key)
openssl_public_encrypt($data, $encrypted, $public_key); //私钥加密
return base64_encode($encrypted);
}
/**
* 用公钥解密私钥加密内容
*
* @param $data
* @param $rsaPublicKey
*
* @return string
*/
public static function decodePrivateEncode($data, $rsaPublicKey)
{
$decrypted = '';
$public_key = openssl_pkey_get_public($rsaPublicKey);
if ($public_key)
openssl_public_decrypt(base64_decode($data), $decrypted, $public_key); //私钥加密的内容通过公钥可用解密出来
return $decrypted;
}
/**
* 用私钥解密公钥加密内容
*
* @param $data
* @param $rsaPrivateKey
*
* @return string
*/
public static function decodePublicEncode($data, $rsaPrivateKey)
{
$decrypted = '';
$private_key = openssl_pkey_get_private($rsaPrivateKey);
if ($private_key)
openssl_private_decrypt(base64_decode($data), $decrypted, $private_key); //私钥解密
return $decrypted;
}
也就是说换一下,就不行了,
但是在各自,自己加密,然后自己解密是可以的。
确定是测试过很多次的,就是不行,换成,私钥加密,公钥解密相互都是可以的,😰,麻烦老哥给看看
是不是编码什么的问题?
Liping Ruan commented
一般来说加解密没通过的原因都是:
- 公私钥不匹配
- 编码格式不统一
- 密钥格式不统一
- 填充方式不统一
根据以上几个原因分析:
- 略过
- 编码肯定是统一的, UTF-8
- 密钥格式肯定是统一的, 都是 PKCS#8 格式
- 填充方式你没传值, 使用的是 PHP 默认值 PKCS1_PADDING, 这里和 JS 端没统一, JS 端默认是 PKCS1_OAEPPadding, 你要么改 JS 端要么改 PHP 端.
JS 端更改与 PHP 端默认统一的填充方式:
rsa.keys.setOptions({encryptionScheme: 'pkcs1'});
PHP 端更改与 JS 端默认统一的填充方式:
openssl_public_encrypt 方法第 4 个参数传OPENSSL_PKCS1_OAEP_PADDING
Addy commented
一般来说加解密没通过的原因都是:
- 公私钥不匹配
- 编码格式不统一
- 密钥格式不统一
- 填充方式不统一
根据以上几个原因分析:
- 略过
- 编码肯定是统一的, UTF-8
- 密钥格式肯定是统一的, 都是 PKCS#8 格式
- 填充方式你没传值, 使用的是 PHP 默认值 PKCS1_PADDING, 这里和 JS 端没统一, JS 端默认是 PKCS1_OAEPPadding, 你要么改 JS 端要么改 PHP 端.
JS 端更改与 PHP 端默认统一的填充方式:
rsa.keys.setOptions({encryptionScheme: 'pkcs1'});
PHP 端更改与 JS 端默认统一的填充方式:
openssl_public_encrypt 方法第 4 个参数传OPENSSL_PKCS1_OAEP_PADDING
- ok
2.ok
3.ok
4.这个有点奇怪,用私钥加密,公钥解密就正常了,难道这样时填充方式就一样了吗?里面是不是存在一点问题呢
Liping Ruan commented
OpenSSL 使用私钥加密时只支持:
- PKCS1_PADDING
- NO_PADDING
排除不安全的 NO_PADDING, 私钥加密都是使用 PKCS1_PADDING
Liping Ruan commented
@zd520ll 老铁问题解决了吗?
Addy commented
已解决,谢谢