Android中的RSAencryption解密

我正在为Android中的RSAencryption和解密实施一个演示。 我可以执行encryption很好,但在解密我得到一个exception: >>java.security.InvalidKeyException: unknown key type passed to RSA

  KeyPairGenerator kpg; KeyPair kp; PublicKey publicKey; PrivateKey privateKey; byte [] encryptedBytes,decryptedBytes; Cipher cipher,cipher1; String encrypted,decrypted; public String RSAEncrypt (final String plain) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { kpg = KeyPairGenerator.getInstance("RSA"); kpg.initialize(1024); kp = kpg.genKeyPair(); publicKey = kp.getPublic(); privateKey = kp.getPrivate(); cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); encryptedBytes = cipher.doFinal(plain.getBytes()); encrypted = new String(encryptedBytes); System.out.println("EEncrypted?????"+encrypted); return encrypted; } public String RSADecrypt (final String result) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { cipher1=Cipher.getInstance("RSA"); cipher1.init(Cipher.DECRYPT_MODE, privateKey); decryptedBytes = cipher1.doFinal(result.getBytes()); decrypted = new String(decryptedBytes); System.out.println("DDecrypted?????"+decrypted); return decrypted; } 

我从这里调用这个函数:

 encrypt.setOnClickListener(new OnClickListener() { public void onClick(View arg0) { try { RSAEncrypt rsaencrypt=new RSAEncrypt(); rsaencrypt.RSAEncrypt(name); result=rsaencrypt.RSAEncrypt(name); Toast.makeText(getBaseContext(), result.toString(),Toast.LENGTH_SHORT).show(); System.out.println("Result:"+result); } catch(Exception e) { e.printStackTrace(); Toast.makeText(getBaseContext(), e.toString(),Toast.LENGTH_LONG).show(); } } }); decrypt.setOnClickListener(new OnClickListener() { public void onClick(View arg0) { { try { RSAEncrypt rsadecrypt=new RSAEncrypt(); rsadecrypt.RSADecrypt(result); ans=rsadecrypt.RSADecrypt(result); System.out.println("Result is"+ans); Toast.makeText(getBaseContext(), ans.toString(),Toast.LENGTH_LONG).show(); } catch(Exception e) { e.printStackTrace(); Toast.makeText(getBaseContext(), e.toString(),Toast.LENGTH_LONG).show(); System.out.println("Exception is>>"+e); } } }); 

Solutions Collecting From Web of "Android中的RSAencryption解密"

在RSA中,您应该使用公钥进行encryption,并使用私钥进行解密。

你的示例代码使用encryption和解密公钥 – 这是行不通的。

因此在解密部分,你应该这样初始化密码:

 cipher1.init(Cipher.DECRYPT_MODE, privateKey); 

深入你的代码有一个重要的错误:

您正在将具有二进制内容的字节数组转换为string。

永远不要将二进制数据转换为string!

string用于string,而不是二进制数据。 如果要将二进制数据打包为string,请将其编码为可打印字符,例如使用hex或Base64。

以下示例使用hex编码器org.apache.common.codec包 – 必须安装第三方库。

 public byte[] RSAEncrypt(final String plain) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { kpg = KeyPairGenerator.getInstance("RSA"); kpg.initialize(1024); kp = kpg.genKeyPair(); publicKey = kp.getPublic(); privateKey = kp.getPrivate(); cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); encryptedBytes = cipher.doFinal(plain.getBytes()); System.out.println("EEncrypted?????" + org.apache.commons.codec.binary.Hex.encodeHexString(encryptedBytes)); return encryptedBytes; } public String RSADecrypt(final byte[] encryptedBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { cipher1 = Cipher.getInstance("RSA"); cipher1.init(Cipher.DECRYPT_MODE, privateKey); decryptedBytes = cipher1.doFinal(encryptedBytes); decrypted = new String(decryptedBytes); System.out.println("DDecrypted?????" + decrypted); return decrypted; } 

我的课:

 package com.infovale.cripto; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.util.Arrays; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; public class RSA { KeyPairGenerator kpg; KeyPair kp; PublicKey publicKey; PrivateKey privateKey; byte[] encryptedBytes, decryptedBytes; Cipher cipher, cipher1; String encrypted, decrypted; public String Encrypt (String plain) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { kpg = KeyPairGenerator.getInstance("RSA"); kpg.initialize(1024); kp = kpg.genKeyPair(); publicKey = kp.getPublic(); privateKey = kp.getPrivate(); cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); encryptedBytes = cipher.doFinal(plain.getBytes()); encrypted = bytesToString(encryptedBytes); return encrypted; } public String Decrypt (String result) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { cipher1=Cipher.getInstance("RSA"); cipher1.init(Cipher.DECRYPT_MODE, privateKey); decryptedBytes = cipher1.doFinal(stringToBytes(result)); decrypted = new String(decryptedBytes); return decrypted; } public String bytesToString(byte[] b) { byte[] b2 = new byte[b.length + 1]; b2[0] = 1; System.arraycopy(b, 0, b2, 1, b.length); return new BigInteger(b2).toString(36); } public byte[] stringToBytes(String s) { byte[] b2 = new BigInteger(s, 36).toByteArray(); return Arrays.copyOfRange(b2, 1, b2.length); } } 

我认为问题是你应该使用相同的密钥对来encryption和解密密码。 引用JavaDoc:

  genKeyPair() This will generate a new key pair every time it is called. 

以下是Android的示例:

  • 生成私有/公共RSA密钥对
  • encryption一个string
  • 解密encryption的string

这些方法处理所有的64位编码/解码。

  public void TestEncryptData(String dataToEncrypt) { // generate a new public/private key pair to test with (note. you should only do this once and keep them!) KeyPair kp = getKeyPair(); PublicKey publicKey = kp.getPublic(); byte[] publicKeyBytes = publicKey.getEncoded(); String publicKeyBytesBase64 = new String(Base64.encode(publicKeyBytes, Base64.DEFAULT)); PrivateKey privateKey = kp.getPrivate(); byte[] privateKeyBytes = privateKey.getEncoded(); String privateKeyBytesBase64 = new String(Base64.encode(privateKeyBytes, Base64.DEFAULT)); // test encryption String encrypted = encryptRSAToString(dataToEncrypt, publicKeyBytesBase64); // test decryption String decrypted = decryptRSAToString(encrypted, privateKeyBytesBase64); } public static KeyPair getKeyPair() { KeyPair kp = null; try { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); kpg.initialize(2048); kp = kpg.generateKeyPair(); } catch (Exception e) { e.printStackTrace(); } return kp; } public static String encryptRSAToString(String clearText, String publicKey) { String encryptedBase64 = ""; try { KeyFactory keyFac = KeyFactory.getInstance("RSA"); KeySpec keySpec = new X509EncodedKeySpec(Base64.decode(publicKey.trim().getBytes(), Base64.DEFAULT)); Key key = keyFac.generatePublic(keySpec); // get an RSA cipher object and print the provider final Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING"); // encrypt the plain text using the public key cipher.init(Cipher.ENCRYPT_MODE, key); byte[] encryptedBytes = cipher.doFinal(clearText.getBytes("UTF-8")); encryptedBase64 = new String(Base64.encode(encryptedBytes, Base64.DEFAULT)); } catch (Exception e) { e.printStackTrace(); } return encryptedBase64.replaceAll("(\\r|\\n)", ""); } public static String decryptRSAToString(String encryptedBase64, String privateKey) { String decryptedString = ""; try { KeyFactory keyFac = KeyFactory.getInstance("RSA"); KeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decode(privateKey.trim().getBytes(), Base64.DEFAULT)); Key key = keyFac.generatePrivate(keySpec); // get an RSA cipher object and print the provider final Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING"); // encrypt the plain text using the public key cipher.init(Cipher.DECRYPT_MODE, key); byte[] encryptedBytes = Base64.decode(encryptedBase64, Base64.DEFAULT); byte[] decryptedBytes = cipher.doFinal(encryptedBytes); decryptedString = new String(decryptedBytes); } catch (Exception e) { e.printStackTrace(); } return decryptedString; } 

当使用RSAEcvypt方法时,它填充公钥和私钥。 当你解密你生成的字节[]时,你的publicKey和privateKey是NULL。 正因为如此,你得到这个错误。

你应该使用你的密钥静态;

 enter code here KeyPairGenerator kpg; KeyPair kp; static PublicKey publicKey; static PrivateKey privateKey; byte [] encryptedBytes,decryptedBytes; Cipher cipher,cipher1; String encrypted,decrypted;