首页 > 解决方案 > 使用 Cipher.doFinal() 进行 RSA 解密不会恢复原始纯文本

问题描述

从原始资源文件生成公钥/私钥对并使用它们在 android 应用程序中加密/解密非常简单。但是,以下代码在 VirtualBox 中使用 Android-x86-v4.4.4 模拟器运行时无法正确恢复纯文本。谁能指出这段代码有什么问题(它不会给出任何错误或产生任何异常):(更改为 Cipher.getInstance("RSA/NONE/NoPadding") 也无济于事)

    PublicKey mPublicKey = null;
    PrivateKey mPrivateKey = null;

    String mPlainText = "The quick brown fox jumped over the lazy dog" ;
    byte[] mEncryptText = null;
    byte[] mDecryptText = null;


    try {
        InputStream mIS = getResources().openRawResource(R.raw.test1_public_key);
        DataInputStream dis = new DataInputStream(mIS);
        byte [] keyBytes = new byte [(int) mIS.available()];
        dis.readFully(keyBytes);
        dis.close();
        mIS.close();
        X509EncodedKeySpec mX509KeySpec = new X509EncodedKeySpec(keyBytes);
        mPublicKey = (KeyFactory.getInstance("RSA")).generatePublic(mX509KeySpec);
        Toast.makeText(this, "Publickey generated", Toast.LENGTH_LONG).show();
    }
    catch(Exception e){
        Log.e("onButtondecrypt", "exception", e);
        Log.e("onButtondecrypt", "exception: " + Log.getStackTraceString(e));
    }

    try {
        InputStream mIS = getResources().openRawResource(R.raw.test1_private_key);
        DataInputStream dis = new DataInputStream(mIS);
        byte [] keyBytes = new byte [(int) mIS.available()];
        dis.readFully(keyBytes);
        dis.close();
        mIS.close();
        PKCS8EncodedKeySpec mPKCS8keySpec = new PKCS8EncodedKeySpec(keyBytes);
        mPrivateKey = (KeyFactory.getInstance("RSA")).generatePrivate(mPKCS8keySpec);
        Toast.makeText(this, "PRIVATE key generated", Toast.LENGTH_LONG).show();
    }
    catch(Exception e){
        Log.e("onButtondecrypt", "exception", e);
        Log.e("onButtondecrypt", "exception: " + Log.getStackTraceString(e));
    }

    Toast.makeText(this, mPlainText, Toast.LENGTH_LONG).show();

    Toast.makeText(this, "Encrypting with Publickey ...", Toast.LENGTH_LONG).show();
    try {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, mPublicKey);
        mEncryptText = cipher.doFinal(mPlainText.getBytes());
        Toast.makeText(this, mEncryptText.toString(), Toast.LENGTH_LONG).show();
    }
    catch(Exception e){
        Log.e("onButtondecrypt", "exception", e);
        Log.e("onButtondecrypt", "exception: " + Log.getStackTraceString(e));
    }

    Toast.makeText(this, "Decrypting with PRIVATE key ...", Toast.LENGTH_LONG).show();
    try {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, mPrivateKey);
        mDecryptText = cipher.doFinal(mEncryptText);
        Toast.makeText(this, mDecryptText.toString(), Toast.LENGTH_LONG).show();
    }
    catch(Exception e){
        Log.e("onButtondecrypt", "exception", e);
        Log.e("onButtondecrypt", "exception: " + Log.getStackTraceString(e));
    }

谢谢大家。

标签: androidencryptionrsa

解决方案


字符串转换为 byte[] 的方式是错误的,反之亦然。正确的方法是

byte[] st = txt.getBytes("UTF-8");

String s = new String(bytes);

因此,加密/解密是正确的,只有吐司显示不正确。


推荐阅读