Bouncy Castle在Android和Console程序上的工作方式不同。如何在PEM文件中使用公钥加密

时间:2015-03-17 12:13:57

标签: java android encryption rsa bouncycastle

我正在使用Bouncy Castle加密。我使用RSA,公钥存储在PEM文件中。我发现当我在简单的控制台项目(而不是Android项目)中运行代码时,一切正常 - 这意味着加密的字符串可以使用私钥解密。但是,当我在Android应用程序中运行相同的代码时,加密的字节数组对于相同的公钥是不同的,并且不会被识别为给定密钥对的有效加密。

详情: 这是使用Bouncy Castle加密字符串并从控制台项目中取出的代码。这个工作正常,并产生加密的字符串,这是密钥对的有效加密,可以解密。

private static void encrypt() {
    try {
        //This example uses the Bouncy Castle library
        Security.addProvider(new BouncyCastleProvider());

        String plainText = "This needs to be encrypted";
        String public_key_file = "PublicKey.pem";

        //Load public key
        PEMParser parser = new PEMParser(new FileReader(public_key_file));
        Object key = parser.readObject();
        parser.close();
        PublicKey pubKey = null;

        if (key instanceof SubjectPublicKeyInfo) {
            SubjectPublicKeyInfo spki = (SubjectPublicKeyInfo) key;
            pubKey = KeyFactory.getInstance("RSA").generatePublic
                    (new X509EncodedKeySpec(spki.getEncoded()));
        }

        //Encrypt the plain text
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        byte[] encrypted_data = cipher.doFinal(plainText.getBytes());
        String encoded_data = new String(Base64.encode(encrypted_data));

        System.out.println("Encrypted Value:");
        System.out.println(encoded_data);
    } catch (Exception ex) {
        System.out.println(ex.getMessage());
    }
}

现在这里是从Android应用程序中取出的代码。唯一重要的区别是从Assets文件夹中读取密钥文件。此代码也会生成加密字符串,但它对密钥对无效,无法解密。

public void encrypt(Context context) {

    try {

        //This example uses the Bouncy Castle library
        Security.addProvider(new BouncyCastleProvider());

        String plainText = "This needs to be encrypted";
        String public_key_file = "PublicKey.pem";

        //Load public key
        InputStream inputStream = context.getAssets().open(public_key_file);
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
        // read from the input stream reader
        PEMParser parser = new PEMParser(inputStreamReader);

        Object key = parser.readObject();
        parser.close();
        PublicKey pubKey = null;

        if (key instanceof SubjectPublicKeyInfo) {
            SubjectPublicKeyInfo spki = (SubjectPublicKeyInfo) key;
            pubKey = KeyFactory.getInstance("RSA").generatePublic
                    (new X509EncodedKeySpec(spki.getEncoded()));
        }

        //Encrypt the plain text
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        byte[] encrypted_data = cipher.doFinal(plainText.getBytes());
        String encoded_data =
                new String(Base64.encode(encrypted_data));

        Log.d("MyApp", "Encrypted Value:");
        Log.d("MyApp", encoded_data);

    } catch (Exception ex) {
        Log.d("MyApp", ex.getMessage());
    }

}

在这两种情况下,事情都是一样的:

  1. 公钥
  2. 写入的实际代码(与Assets文件夹的读数不同,并记录到Logcat)
  3. JDK版本(1.7)
  4. Bouncy Castle图书馆(bcpkix-jdk15on-152.jar和bcprov-jdk15on-152.jar)
  5. 与众不同:环境。一个是控制台程序,另一个是Android App。

    调试时进一步调查 我观察到,当运行控制台程序时,KeyFactory返回" sun.security.rsa.RSAPublicKeyImpl"的实例。但是,当运行Android应用程序时,KeyFactory返回" com.android.org.conscrypt.OpenSSLRSAPublicKey"的实例。不确定这是不是问题所在。对于相同的纯文本和公钥,加密的字节数组是不同的。

    非常感谢任何帮助。

    先谢谢, 和Sandeep

0 个答案:

没有答案