您的位置:首页 > 移动开发 > Android开发

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

2012-12-22 13:06 701 查看
最近做的项目需要用到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上正常加密了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: