Asi*_*kht 6 android rsa bouncycastle phpseclib pidcrypt
我已经使用php,javascript和android应用程序使用库实现了RSA加密:
php侧的phpseclib
pidcrypt for javascript
bouncrycastle版本(bcprov-jdk14-151)用于anrdroid serviceprovider
我有我的加密机制,如:
user->request->publickey
->server->generate(publickey,privatekey) and save private key into Database
->server->sendpublickey->user
->user->encryptdata->send->server->decrypt
Run Code Online (Sandbox Code Playgroud)
但是这种机制在javascript和php加密和解密之间工作正常,但在服务器发送公钥时在android平台上.它无法解密公钥.
现在我为此测试了不同的场景
PHP KeyGenerating
$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));
Run Code Online (Sandbox Code Playgroud)
PHP DecryptingCode
$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);
Run Code Online (Sandbox Code Playgroud)
就像我的公钥一样.
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBALrBdN8F83hT2+pBsAwiNx+v3FWp51IdEElE8UvVhfZYmePbitpzLcJi
jZ4/tvRFXJGhqa3PKPUQkH2F4VrHruA2kNceiL/Btywc9oM+tDMeX1jcRKwXwK1k
KdccKwn0qywG6YxQuqWQIotOfV+IIuhcHdaHBl6CZ05/cBo6AlMlAgMBAAE=
-----END RSA PUBLIC KEY-----
Run Code Online (Sandbox Code Playgroud)
从服务器和服务器请求密钥生成公钥和私钥,并将公钥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);
Run Code Online (Sandbox Code Playgroud)此代码无法解密消息,我从PHP SIDE收到此错误
Decryption error in /security/RSA.php on line **2493**
Run Code Online (Sandbox Code Playgroud)
RSA.php 2493代码
if (ord($em[0]) != 0 || ord($em[1]) > 2) {
user_error('Decryption error');
return false;
}
Run Code Online (Sandbox Code Playgroud)
第二种情况是获取publick键字符串并解析它
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);
Run Code Online (Sandbox Code Playgroud)有这个我得到错误
java.security.spec.InvalidKeySpecException:
java.lang.ClassCastException: com.android.org.bouncycastle.asn1.DERApplicationSpecific
cannot be cast to com.android.org.bouncycastle.asn1.ASN1Sequence
Run Code Online (Sandbox Code Playgroud)
我知道编码的公钥是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());
Run Code Online (Sandbox Code Playgroud)我忘记了它的错误
unable to cast pemObject to asymmetric ( not sure but something like that )
Run Code Online (Sandbox Code Playgroud)
我甚至尝试了以下链接中的一些代码,但我得到了不同的错误.
RSA Android加密/ RSA PHP解密 PhpSeclib < - > BouncyCastle RSA
请查看代码并帮助我.
好的,经过几个小时的EXPONENT和MODULUS工作后, 我已经成功地加密和解密了 android 应用程序和 php 服务器之间的数据,这是可能对某人来说很方便的解决方案
我的错误是,当密码数据准备好编码时,我使用的是JAVA内部 BASE64 类,它生成 x2 大小的编码数据,而 php 有不同的解码和编码机制(我不太确定这只是猜测)
所以为了无效我使用了APACHE commons-codec-1.8 库,这里是正确的代码
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(plainText.getBytes("UTF-8"));//
byte[] coded = Base64.encodeBase64(encryptedBytes); //used library encode decode
String encryptedData = new String(encodedBytes);
Run Code Online (Sandbox Code Playgroud)
最后一行是将密码二进制数据编码为 BASE64
我将进一步了解JAVA和PHP之间的BASE64差异
谢谢
| 归档时间: |
|
| 查看次数: |
1413 次 |
| 最近记录: |