2016-07-26 60 views
2

我在java中加密一个单词,我无法在php中解密它。RSA - 在Android中加密/解密在PHP中

这里是我创造的Android按键:

public void GenerateAndSaveToFile(){ 
    try { 

     KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 
     kpg.initialize(1024); 
     KeyPair kp = kpg.genKeyPair(); 
     Key publicKey = kp.getPublic(); 
     Key privateKey = kp.getPrivate(); 
     KeyFactory fact = KeyFactory.getInstance("RSA"); 
     RSAPublicKeySpec pub = fact.getKeySpec(kp.getPublic(), RSAPublicKeySpec.class); 
     RSAPrivateKeySpec priv = fact.getKeySpec(kp.getPrivate(), RSAPrivateKeySpec.class); 
     ////////////////////////// 
     String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString(); 
     File myDir = new File(root + "/keys"); 
     myDir.mkdirs(); 
     File file = new File (myDir, "private.key"); 
     FileOutputStream fileout1 = new FileOutputStream(file); 
     ObjectOutputStream oout1 = new ObjectOutputStream(fileout1); 
     oout1.writeObject(priv.getModulus()); 
     oout1.writeObject(priv.getPrivateExponent()); 
     oout1.close(); 
     /////////////////////// 
     File file2 = new File (myDir, "public.key"); 
     FileOutputStream fileout2 = new FileOutputStream(file2); 
     ObjectOutputStream oout2 = new ObjectOutputStream(new BufferedOutputStream(fileout2)); 
     oout2.writeObject(pub.getModulus()); 
     oout2.writeObject(pub.getPublicExponent()); 
     oout2.close(); 

    } 
    catch (Exception ex){ 
     Exception e = ex; 
    } 

} 

这里是我如何加密在android系统与生成的公钥字:

byte[] u1Encrypted = RSAEncrypt(String.valueOf(inputEmail.getText()).getBytes()); 

public byte[] RSAEncrypt(byte[] data) { 
    try { 
     PublicKey pubKey = ReadPublicKey(); 
     Cipher cipher = Cipher.getInstance("RSA"); 
     cipher.init(Cipher.ENCRYPT_MODE, pubKey); 
     byte[] cipherData = cipher.doFinal(data); 
     return cipherData; 
    }   
    catch (Exception ex) 
    { 
     Exception e = ex; 
     return null; 
    } 

} 


private PublicKey ReadPublicKey() throws IOException { 
    try { 
     AssetManager assetManager = getAssets(); 
     InputStream in = assetManager.open("public.key"); 
     ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(in)); 

     try { 

      BigInteger m = (BigInteger) oin.readObject(); 
      BigInteger e = (BigInteger) oin.readObject(); 
      RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e); 
      KeyFactory fact = KeyFactory.getInstance("RSA"); 
      PublicKey pubKey = fact.generatePublic(keySpec); 
      return pubKey; 
     } catch (Exception e) { 
      throw new RuntimeException("Spurious serialisation error", e); 
     } finally { 
      oin.close(); 
     } 
    } 
    catch (Exception ex) 
    { 
     Exception e = ex; 
     return null; 
    } 
} 

然后我加密的字符串转换为Base64在android中:

String u1EncryptedBase64 = Base64.encodeToString(u1Encrypted, Base64.DEFAULT); 

在php中解码base64字符串:

$encryptedString = base64_decode(u1EncryptedBase64); 

获得私钥:

$keytmp = fopen("../../../private.key", "r") or die("Unable to open file!"); 
$key = fread($keytmp,filesize("../../../private.key")); 
$res = openssl_get_privatekey($key); 

,最后我尝试解密字符串在PHP中:

if (openssl_private_decrypt($encryptedString, $decrypted, $res)) { 

    echo $decrypted; 
} 
else 
{ 
    echo "problem"; 
} 

和错误我得到的是:

警告:openssl_private_decrypt ():密钥参数不是有效的私钥...

请指导我如何完成这项任务。 谢谢

+0

'openssl_get_privatekey'需要一个PEM编码的私钥。那是你在Java中创建的吗? (并且你想要PEM编码的可能是'privateKey.getEncoded()')。 – Michael

+0

@Michael,不,我认为这不是PEM编码的。我不确定KeyFactory.getInstance(“RSA”)生成的格式是什么。 – farhang67

回答

1

你可以通过使用该私钥解密在android部分的字符串?

我想你可以先尝试一下。至少会知道问题是由密钥生成引起的,或者是在php中获取私钥的功能。

+0

是的我可以用android中的私钥解密字符串。 – farhang67