PHP服务器生成密钥,java端加密,php解密的方法。更新Android加密方法

本文介绍了如何在PHP中生成DER格式的RSA密钥对,以及如何在Java和Android平台上进行RSA加密和解密操作。详细解释了关键步骤和代码实现,解决了跨平台兼容性问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近做的项目需要用到RSA加密解密的功能,并且是在不同的平台进行。详细的说是在PHP服务器上生成Key Pair,然后Java端通过请求获得公钥加密后发给php,然后在php通过密钥解密。

虽然我们手上有一份别人做过的源码,但那份源码里是通过Openssl生成 .der 格式的Key Pair,然后java下载了公钥之后进行加密。然而我们现在的项目的服务器是租用的,不能用php执行exec等命令,而java端的源码里却是必须通过读取 .der 文件才能进行加密。我为此谷歌了好久也没找到php如何生成 .der 文件的方式,有些方法虽然生成了 .der 文件,但是里边的编码方式不同,还是无法使用。

因此我就去找不需要 Openssl 又能正常加密解密的方法。最后找到了一个。

PHP生成Key Pair代码:

function createKey()
{
    $privateKey = openssl_pkey_new(array(
        'private_key_bits' => 1024,
        'private_key_type' => OPENSSL_KEYTYPE_RSA
    ));
    echo openssl_error_string()."<br />";
    $keyDetails = openssl_pkey_get_details($privateKey);
    $publicKey = $keyDetails['key'];
    openssl_pkey_export_to_file($privateKey, '/private.key', $password);
    file_put_contents('./public.key', $publicKey);
}

这样就能生成 Key Piar 了。

然后Java端获得类似这样的公钥:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDP2PjJgQBdV5c10aF45LF4spzF
6b35XKeN2yyQN9+9IvtjgtK62GJJSfnhXHMZMkGwhONcT2iaLD8gs9vRxlW7c2nf
cIYwMGSe4OAcUOanUn7aZzgpwX1DCAF3NIMcqFot\/R15WiiBZdjFohaFPVgTWFNG
RPJi2PVgcEFusFI\/cwIDAQAB
-----END PUBLIC KEY-----

然后只需要中间那段。下面是Java端的代码

    String key = getPublicKey();
    System.out.println("公钥 " + key);
    java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec(
        new BASE64Decoder().decodeBuffer(key));
    // RSA对称加密算法
    java.security.KeyFactory keyFactory;
    keyFactory = java.security.KeyFactory.getInstance("RSA");
    // 取公钥匙对象
    PublicKey publicKey = keyFactory.generatePublic(bobPubKeySpec);
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    String text = "1231456";
    byte[] encrypted = cipher.doFinal(text.getBytes());

这样 encrypted 就是加密后的数据了。如果要想通过 URL 发送的话还得用Base64编码一下。

最后,是在PHP的解密:

$privateKey = openssl_pkey_get_private("file://./private.key", $password);
openssl_private_decrypt($encryptedData, $originData, $this->privateKey);

这个 origrinData 就是解密后的数据了。

这样的方法用Java可以正常加密,但是放到Android上就不行,服务器不能正常解密。调试了一下发现Android加密后用Base64编码后内容不变,因此猜想是加密部分出了问题。又上网搜索,调试了两天,发现解决的办法。

其实在Android和Java的加密的方法是基本上一样的,只是有些参数不同。

    String key = u.getPublicKey();
    System.out.println("公钥 " + key);
    java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec(
        new BASE64Decoder().decodeBuffer(key));
    // RSA对称加密算法
    java.security.KeyFactory keyFactory;
    keyFactory = java.security.KeyFactory.getInstance("RSA");
    // 取公钥匙对象
    PublicKey publicKey = keyFactory.generatePublic(bobPubKeySpec);
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");    //这一句代码不同
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    String text = "1231456";
    byte[] encrypted = cipher.doFinal(text.getBytes());

这样就可以在Android上正常加密了。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值