lipingruan / fucking-util-signature-all

node/go/web/h5/uni-app/mui/移动端/小程序/签名/验证/加密/解密/RSA/SHA/MD5/sign/verify/encrypt/decrypt

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

老铁,还得麻烦看看,uniapp公钥加密,服务端[php]对应私钥解密,无法解密

byphp-com opened this issue · comments

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;
    }

也就是说换一下,就不行了,
但是在各自,自己加密,然后自己解密是可以的。
确定是测试过很多次的,就是不行,换成,私钥加密,公钥解密相互都是可以的,😰,麻烦老哥给看看
是不是编码什么的问题?

一般来说加解密没通过的原因都是:

  1. 公私钥不匹配
  2. 编码格式不统一
  3. 密钥格式不统一
  4. 填充方式不统一

根据以上几个原因分析:

  1. 略过
  2. 编码肯定是统一的, UTF-8
  3. 密钥格式肯定是统一的, 都是 PKCS#8 格式
  4. 填充方式你没传值, 使用的是 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
commented

一般来说加解密没通过的原因都是:

  1. 公私钥不匹配
  2. 编码格式不统一
  3. 密钥格式不统一
  4. 填充方式不统一

根据以上几个原因分析:

  1. 略过
  2. 编码肯定是统一的, UTF-8
  3. 密钥格式肯定是统一的, 都是 PKCS#8 格式
  4. 填充方式你没传值, 使用的是 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
  1. ok
    2.ok
    3.ok
    4.这个有点奇怪,用私钥加密,公钥解密就正常了,难道这样时填充方式就一样了吗?里面是不是存在一点问题呢

OpenSSL 使用私钥加密时只支持:

  1. PKCS1_PADDING
  2. NO_PADDING

排除不安全的 NO_PADDING, 私钥加密都是使用 PKCS1_PADDING

@zd520ll 老铁问题解决了吗?

commented

已解决,谢谢