RSA Android 加密 / RSA PHP 解密

发布于 2024-12-03 08:25:00 字数 3246 浏览 1 评论 0原文

我需要一些帮助来解决我的问题。

问题 : 我想使用 Android 平台上的公共 RSA 密钥对数字 (A) 进行加密,然后使用私钥在 PHP 服务器上对其进行解密。 在每个平台上,我都可以加密和解密数据(效果很好),但是当PHP脚本尝试解密从ANDROID加密的数据时,它不起作用!

问题不是来自 HTTP 传输,因为我尝试直接解密从 ANDROID 生成的加密(以 Base64 编码),但它根本不起作用...

在我的用于解密数据的 PHP 代码之后找到这里:

class MyEncryption
{

public $privkey = '';
public $pubkey = '';
public function __construct(){

}

public function initialize() {
    $fp=fopen("./encryption/asasap_public.pub","r");
    $temp=fread($fp,8192);
    fclose($fp);
    $this->pubkey = openssl_pkey_get_public($temp);

    $fp=fopen("./encryption/asasap.pem","r");
    $temp=fread($fp,8192);
    fclose($fp);
    $this->privkey = openssl_get_privatekey($temp,'');

}

public function encrypt($data)
{
    if (openssl_public_encrypt($data, $encrypted, $this->pubkey))
        $data = base64_encode($encrypted);
    else
        throw new Exception('Unable to encrypt data. Perhaps it is bigger than the key size?');

    return $data;
}

public function decrypt($data)
{
    if (openssl_private_decrypt(base64_decode($data), $decrypted, $this->privkey))
        $data = $decrypted;
    else
        $data = '';

    return $data;
}

public function hex2bin($hexdata) {
    $bindata = '';

    for ($i = 0; $i < strlen($hexdata); $i += 2) {
        $bindata .= chr(hexdec(substr($hexdata, $i, 2)));
    }

    return $bindata;
}
}

我在这里使用此类:

$enc = new MyEncryption();
$enc->initialize();
$data_1 = 'K27booXr0zZK4BQlI45MIPJJjPPkpCCPELGvoK/wKYUwShIWE6szlZtrmV83C5eBIrT/3lxWTH3+IOA+5mefurVUvXmQIV7fXEHNHLphyM6L9gQsMAGZMCroPjWKvJM59OMS/d5dwwhiRgzVarxXSKpxBYhEYWJTu7nRJ+bZKjumeoqnCSpmntIiV+tRYgkYflOU6j2QlesjO5tzj/TL6n7vHSO/O1qafJkzHcv8Kn2hTy+IH7QXm7z5vtjXOucHkvBm1xWORXdifh+ChyVvP16dSEmCaCAH6KqtA4viX/HwRFEi4mIWaYSIQk74NdcnQOpFcTgEu2nDwtHaBMqahw==';
$data_2 = $enc->decrypt($data_1);

这里data_1 是使用 RSA 公钥从 Android 的加密数据 (A=5) 初始化的(注意:解密在 Android 上运行良好),但在 PHP 中解密后,我得到空字符串 ...

-------- ---------------------------------- 更新 -------

请在 ANDROID 部分的代码后面找到:

public byte[] encryptRSA(final InputStream publicKeyFile, String in) throws IOException, NoSuchAlgorithmException,
    InvalidKeySpecException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException,
    BadPaddingException {
    byte[] encodedKey = new byte[5000];
    publicKeyFile.read(encodedKey);
    X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PublicKey pkPublic = kf.generatePublic(publicKeySpec);
    // Encrypt
    Cipher pkCipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
    pkCipher.init(Cipher.ENCRYPT_MODE, pkPublic);
    return pkCipher.doFinal(in.getBytes());
}

加密数据后,我将 byte[] 转换为 Base64 (Base64.encodeToString(input, Base64.DEFAULT))。

对于证书,我使用 RSA 2048 位转换为适用于 Android 的 DER 格式。

- - - - - - - - - - - - - - - - - - - - - 解决方案 - - - -

错误在以下几行:

byte[] encodedKey = new byte[5000];
publicKeyFile.read(encodedKey);

我们必须准确读取公钥:

byte[] encodedKey = new byte[/*lenght of file*/];
publicKeyFile.read(encodedKey);

i need some help for solve my problem.

Problem :
I want to encrypt a number (A) with public RSA Key from Android platform and then decrypt it on PHP Server with the private key.
On each platform, i can encrypt and decrypt data (it works well), but when the PHP script try to decrypt data encrypted from ANDROID, it doesn't work !!

Problem is not from HTTP Transmission, because I try to decrypt directly a generating Encryption from ANDROID (coded in Base64) and it not work at all ...

Findhere after my PHP Code for decrypt data :

class MyEncryption
{

public $privkey = '';
public $pubkey = '';
public function __construct(){

}

public function initialize() {
    $fp=fopen("./encryption/asasap_public.pub","r");
    $temp=fread($fp,8192);
    fclose($fp);
    $this->pubkey = openssl_pkey_get_public($temp);

    $fp=fopen("./encryption/asasap.pem","r");
    $temp=fread($fp,8192);
    fclose($fp);
    $this->privkey = openssl_get_privatekey($temp,'');

}

public function encrypt($data)
{
    if (openssl_public_encrypt($data, $encrypted, $this->pubkey))
        $data = base64_encode($encrypted);
    else
        throw new Exception('Unable to encrypt data. Perhaps it is bigger than the key size?');

    return $data;
}

public function decrypt($data)
{
    if (openssl_private_decrypt(base64_decode($data), $decrypted, $this->privkey))
        $data = $decrypted;
    else
        $data = '';

    return $data;
}

public function hex2bin($hexdata) {
    $bindata = '';

    for ($i = 0; $i < strlen($hexdata); $i += 2) {
        $bindata .= chr(hexdec(substr($hexdata, $i, 2)));
    }

    return $bindata;
}
}

And i use this class like here :

$enc = new MyEncryption();
$enc->initialize();
$data_1 = 'K27booXr0zZK4BQlI45MIPJJjPPkpCCPELGvoK/wKYUwShIWE6szlZtrmV83C5eBIrT/3lxWTH3+IOA+5mefurVUvXmQIV7fXEHNHLphyM6L9gQsMAGZMCroPjWKvJM59OMS/d5dwwhiRgzVarxXSKpxBYhEYWJTu7nRJ+bZKjumeoqnCSpmntIiV+tRYgkYflOU6j2QlesjO5tzj/TL6n7vHSO/O1qafJkzHcv8Kn2hTy+IH7QXm7z5vtjXOucHkvBm1xWORXdifh+ChyVvP16dSEmCaCAH6KqtA4viX/HwRFEi4mIWaYSIQk74NdcnQOpFcTgEu2nDwtHaBMqahw==';
$data_2 = $enc->decrypt($data_1);

Here data_1 is initialized from the encrypt data (A=5) from android with the RSA Public Key (note : decrypt works well on Android), but after decryption in PHP, i get empty String ...

------------------------------------------ UPDATE -------

Please find here after the code for ANDROID part :

public byte[] encryptRSA(final InputStream publicKeyFile, String in) throws IOException, NoSuchAlgorithmException,
    InvalidKeySpecException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException,
    BadPaddingException {
    byte[] encodedKey = new byte[5000];
    publicKeyFile.read(encodedKey);
    X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PublicKey pkPublic = kf.generatePublic(publicKeySpec);
    // Encrypt
    Cipher pkCipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
    pkCipher.init(Cipher.ENCRYPT_MODE, pkPublic);
    return pkCipher.doFinal(in.getBytes());
}

After encrypt data, i convert the byte[] into Base64 (Base64.encodeToString(input, Base64.DEFAULT)).

For the certificate, i use RSA 2048 Bits convert into DER Format for Android.

------------------------------------------ SOLUTION -------

Error are in following Lines :

byte[] encodedKey = new byte[5000];
publicKeyFile.read(encodedKey);

We must read exactely the Public Key :

byte[] encodedKey = new byte[/*lenght of file*/];
publicKeyFile.read(encodedKey);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

久随 2024-12-10 08:25:00

有很多地方可能会出错:

  1. 您正在向 X509EncodedKeySpec 传递 5000 字节,其中大部分为 0。您确定获得了正确的公钥吗?
  2. in 字符串有多长?
  3. String.getBytes() 使用平台默认编码,可能会产生意想不到的结果。使用 getBytes("ASCII")getBytes("UTF-8")

一般来说,您应该只使用 SSL,不要尝试自己实现非对称加密。

There are a lot of places this can go wrong:

  1. You are passing 5000 bytes to X509EncodedKeySpec, most of which are 0. Are you sure you are getting the proper public key?
  2. How long is the in String?
  3. String.getBytes() uses the platform default encoding and may have unintended results. Use getBytes("ASCII") or getBytes("UTF-8").

Generally, you should just use SSL, and don't try to implement asymmetric encryption yourself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文