我已经使用库在 php、javascript 和 android 应用程序中实现了 RSA 加密:
phpseclib用于 php 端
用于 javascript 的pidcrypt
bouncrycastle 版本(bcprov-jdk14-151),适用于安卓服务提供者
我有我的加密机制,如:
user->request->publickey
->server->generate(publickey,privatekey) and save private key into Database
->server->sendpublickey->user
->user->encryptdata->send->server->decrypt
然而,这种机制在 javascript 和 php 加密和解密之间运行良好,但在 android 平台上,当服务器发送公钥时。它无法解密公钥。
现在我已经为此测试了不同的场景
PHP 密钥生成
$rsa = new Crypt_RSA();
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS1);
define('CRYPT_RSA_EXPONENT', 65537);
extract($rsa->createKey(1024));
PHP解密代码
$rsa = new Crypt_RSA();
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
$rsa->loadKey($pri);
$binaryCiphertext=base64_decode($encrypted);
$strBase64DecryptedData=$rsa->decrypt($binaryCiphertext);
$plaintText = base64_decode($strBase64DecryptedData);
就像我的公钥一样。
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBALrBdN8F83hT2+pBsAwiNx+v3FWp51IdEElE8UvVhfZYmePbitpzLcJi
jZ4/tvRFXJGhqa3PKPUQkH2F4VrHruA2kNceiL/Btywc9oM+tDMeX1jcRKwXwK1k
KdccKwn0qywG6YxQuqWQIotOfV+IIuhcHdaHBl6CZ05/cBo6AlMlAgMBAAE=
-----END RSA PUBLIC KEY-----
来自服务器的请求密钥和服务器生成公钥和私钥并将公钥MODULUS和EXPONENT发送到 android 应用程序并应用此代码:
RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(mod,exp); KeyFactory keyFactory = KeyFactory.getInstance("RSA","BS"); PublicKey publicKey = keyFactory.generatePublic(rsaPublicKeySpec); Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding", "BS"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] encryptedBytes = cipher.doFinal(plaintText.getBytes()); byte[] encodedBytes = org.bouncycastle.util.encoders.Base64.encode(encryptedBytes); String encryptedData = new String(encodedBytes);
此代码无法解密消息,我从 PHP SIDE 收到此错误
Decryption error in /security/RSA.php on line **2493**
RSA.php 2493 代码
if (ord($em[0]) != 0 || ord($em[1]) > 2) {
user_error('Decryption error');
return false;
}
第二种情况是获取公钥字符串并解析它
byte[] keyBytes = Base64.decode(keyString, Base64.DEFAULT); String rsaPublicKeyString = new String(keyBytes); String sliceKeyHeader = rsaPublicKeyString.replaceAll("(-+BEGIN RSA PUBLIC KEY-+\\r?\\n|-+END RSA PUBLICKEY-+\\r?\\n?)", ""); byte[] encodedDER = Base64.encode(sliceKeyHeader.getBytes(),Base64.DEFAULT); X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedDER); KeyFactory kf = KeyFactory.getInstance("RSA","BC"); PublicKey pkPublic = (PublicKey) kf.generatePublic(publicKeySpec);
有了这个我得到错误
java.security.spec.InvalidKeySpecException:
java.lang.ClassCastException: com.android.org.bouncycastle.asn1.DERApplicationSpecific
cannot be cast to com.android.org.bouncycastle.asn1.ASN1Sequence
我知道编码的公钥是 DER 编码的,但我仍然不知道该怎么做 --- 我想有人可以指导我使用 DER 编码解码 ---
第三种情况是
final Reader reader = new StringReader(rsaPublicKeyString); PemReader pemReader = new PemReader(reader); PemObject pemObject= pemReader.readPemObject(); pemReader.close(); AsymmetricKeyParameter publicKey = PublicKeyFactory.createKey(pemObject.getContent());
我忘记了它的错误
unable to cast pemObject to asymmetric ( not sure but something like that )
我什至尝试了以下链接中的一些代码,但我得到了不同的错误。
RSA Android 加密/RSA PHP 解密 PhpSeclib <-> BouncyCastle RSA
请查看代码并帮助我。