繁体   English   中英

Android中的RSA公钥实现

[英]RSA Publickey implemenation in android

我已经在使用库的php,javascript和android应用中使用RSA加密技术:

  1. phpseclib用于php端

  2. pidcrypt用于javascript

  3. 机器人服务提供者的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-----
  1. 来自服务器的请求密钥和服务器生成公钥和私钥,并将公钥MODULUSEXPONENT发送到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;
 }
  1. 第二种情况是获取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); 

与此我得到错误

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编码解码来指导我-

  1. 第三种情况是

      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

请研究代码并为我提供帮助。

OK经过数小时使用EXPONENTMODULUS的工作,我已经成功地加密和解密了android app和php server之间的数据,这是可能对某些人有用的解决方案

我的错误是,当密码数据准备好进行编码时,我正在使用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);

最后第二行是将密码二进制数据编码为BASE64

我将了解有关JAVA和PHP之间的BASE64差异的更多信息

谢谢

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM