Android:使用存储在文件中的公钥解密RSA文本

the*_*man 16 encryption android rsa

我已经好几天没试成功了.

StackOverflow中有很多类似的问题,甚至其中有两个与我的完全相同,但是没有答案和未解决:1)将PHP RSA PublicKey转换为Android PublicKey 2)Android:如何使用RSA密钥解密openssl加密文件?

我的场景:我有一些使用RSA加密的文本(未经我加密).我在res/raw文件夹中有一个"public.key"文件,其中包含解密所需的公钥(与用于加密消息的私钥相关的公钥),格式如下例所示: 在此输入图像描述

我看到很多关于如何解密RSA文本的例子,如下所示:

public static byte[] decryptRSA( PublicKey key, byte[] text) throws Exception
      { 
          byte[] dectyptedText = null;

          Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
          cipher.init(Cipher.DECRYPT_MODE, key);
          dectyptedText = cipher.doFinal(text);
          return dectyptedText;
      }
Run Code Online (Sandbox Code Playgroud)

但我的问题是,如何从文件中获取正确的PublicKey实例?没有这方面的例子.

如果我只是尝试:

    InputStream is = getResources().openRawResource(R.raw.public);
    DataInputStream dis = new DataInputStream(is);
    byte [] keyBytes = new byte [(int) is.available()];
    dis.readFully(keyBytes);
    dis.close();
    X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    return keyFactory.generatePublic(spec);
Run Code Online (Sandbox Code Playgroud)

我在返回句子中得到一个InvalidKeyException.我需要解码Hex或Base64吗?公钥文件的第一行和最后一行是不是有问题(带有"---- BEGIN PUBLIC KEY ----"等等)?

也许我们可以在StackOverflow中第一次正确地得到这个答案:-)

the*_*man 13

终于解决了!!! 鼓,喇叭和迷人的交响声!

public static byte[] decryptRSA(Context mContext, byte[] message) throws Exception { 

    // reads the public key stored in a file
    InputStream is = mContext.getResources().openRawResource(R.raw.sm_public);
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    List<String> lines = new ArrayList<String>();
    String line = null;
    while ((line = br.readLine()) != null)
        lines.add(line);

    // removes the first and last lines of the file (comments)
    if (lines.size() > 1 && lines.get(0).startsWith("-----") && lines.get(lines.size()-1).startsWith("-----")) {
        lines.remove(0);
        lines.remove(lines.size()-1);
    }

    // concats the remaining lines to a single String
    StringBuilder sb = new StringBuilder();
    for (String aLine: lines)
        sb.append(aLine);
    String keyString = sb.toString();
    Log.d("log", "keyString:"+keyString);

    // converts the String to a PublicKey instance
    byte[] keyBytes = Base64.decodeBase64(keyString.getBytes("utf-8"));
    X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PublicKey key = keyFactory.generatePublic(spec);

    // decrypts the message
    byte[] dectyptedText = null;
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.DECRYPT_MODE, key);
    dectyptedText = cipher.doFinal(Base64.decodeBase64(message));
    return dectyptedText;
}
Run Code Online (Sandbox Code Playgroud)

解决方案是Base64解码不仅是从文件读取的公钥,还包括加密的消息本身!

顺便说一句,我从@Nikolay建议的方式读取文件中的公钥(tnx再次man).

非常感谢你的帮助.StackOverflow摇滚!