BadPaddingException:无效的密文BadPaddingException

2023-09-04 23:16:30 作者:把酒祝东风

我想一些帮助,因为这是我第一次在编码加密code。

I would like some help as this is my first time in coding cryptography code.

加密code似乎一切正常,但解密引发错误。

The encryption code appears to be working correctly, but the decryption throws an error.

我得到的错误是:

de.flexiprovider.api.exceptions.BadPaddingException:无效的密文

在解密功能对的code,其中被标记为注释结束

in the decrypt function towards the end of the code, which is marked as a comment

//错误时,抛出这里! ..............................

// ERROR THROWN HERE! ..............................

我已经包括了所有的进口,请原谅这一点,因为认为它可能与问题相关的。

I have included all the imports, please excuse this, as thought it maybe relevant to the issue.

任何帮助,以什么我做错了会大大AP preciated,非常感谢。

Any help as to what I am doing wrong will be greatly appreciated, thanks very much.

code:

import java.io.UnsupportedEncodingException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;

import android.app.Activity;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import de.flexiprovider.common.ies.IESParameterSpec;
import de.flexiprovider.core.FlexiCoreProvider;
import de.flexiprovider.ec.FlexiECProvider;
import de.flexiprovider.ec.parameters.CurveParams;
import de.flexiprovider.ec.parameters.CurveRegistry.BrainpoolP384r1;
import de.flexiprovider.pki.PKCS8EncodedKeySpec;
import de.flexiprovider.pki.X509EncodedKeySpec;

public class MainActivity extends Activity {

private static PublicKey PublicKey;
private static PrivateKey PrivateKey;
private static String PubKey;
private static String PrvKey;
private static String message = "Hello World";
private static String encryptedMessage;
private static String decryptedMessage;

private final static String TAG = "ERROR: ";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    try {
        Security.addProvider(new FlexiCoreProvider());
        Security.addProvider(new FlexiECProvider());

        // instantiate the elliptic curve key pair generator
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECIES", "FlexiEC");

        // choose the curve
        CurveParams ecParams = new BrainpoolP384r1();

        // Initialize the key pair generator
        kpg.initialize(ecParams, new SecureRandom());
        KeyPair keyPair = kpg.generateKeyPair();

        // generate the public key
        PublicKey = keyPair.getPublic();

        // generate private key
        PrivateKey = keyPair.getPrivate();
    }
    catch (Exception e) {
        Log.e(TAG, e.toString());
    }

    // I'm converting keys to strings here as the public keys will be stored on a server
    // database and the private keys will be stored in the application preferences file
    // this private key storage is maybe not optimum, but at this point I just want to
    // simulate a messaging encryption/decryption process for testing purposes

    // convert public key to a string
    PubKey = Base64.encodeToString(PublicKey.getEncoded(), Base64.DEFAULT);
    Log.d("PubKey: ", PubKey);

    // convert private key to a string
    PrvKey = Base64.encodeToString(PrivateKey.getEncoded(), Base64.DEFAULT);
    Log.d("PrvKey: ", PrvKey);

    // encrypt the message with the public key
    encryptedMessage = encryptMessage(PubKey, message);

    // report if the public key has not been regenerated correctly
    if (encryptedMessage == null) {
        Log.d("PUBLIC_KEY_REGENERATE_ERROR: ", encryptedMessage);
    }

    // decrypt the message with the private key
    decryptedMessage = decryptMessage(PrvKey, encryptedMessage);

    // report if the private key has not been regenerated correctly
    if (encryptedMessage == null) {
        Log.d("PRIVATE_KEY_REGENERATE_ERROR: ", decryptedMessage);
    }
}

// encrypt function
public static String encryptMessage(String publicKey, String message) {

    KeyFactory keyFactory = null;
    PublicKey pubkey = null;
    Cipher cipher = null;

    byte[] PLAINTEXT_MESSAGE = message.getBytes();
    Log.d("PLAINTEXT_MESSAGE: ", message);

    Security.addProvider(new FlexiCoreProvider());
    Security.addProvider(new FlexiECProvider());

    // Base64 decode the publicKey string into a byte array
    byte[] decodedPublicKey = Base64.decode(publicKey, Base64.DEFAULT);

    try {
        // instantiate a X509EncodedKeySpec
        X509EncodedKeySpec X509spec = new X509EncodedKeySpec(decodedPublicKey);

        keyFactory = KeyFactory.getInstance("ECIES", "FlexiEC");

        // re-generate the public key
        pubkey = keyFactory.generatePublic(X509spec);

        // sanity check, return null on inequality
        if (!pubkey.equals(PublicKey)) {
            return null;
        }

        cipher = Cipher.getInstance("ECIES", "FlexiEC");
        IESParameterSpec IESspec = new IESParameterSpec("AES256_CBC", "HmacSHA512", null, null);
        cipher.init(Cipher.ENCRYPT_MODE, pubkey, IESspec);
    }
    catch (Exception e) {
        Log.e(TAG, e.toString());
    }

    // encrypt the message
    byte[] encryptedData = null;

    try {
        encryptedData = cipher.doFinal(PLAINTEXT_MESSAGE);
    }
    catch (IllegalBlockSizeException e) {
        Log.e(TAG, e.toString());
    }
    catch (BadPaddingException e) {
        Log.e(TAG, e.toString());
    }

    String encryptedMessage = null;

    try {
        encryptedMessage = new String(encryptedData, "UTF-8");
    }
    catch (UnsupportedEncodingException e) {
        Log.e(TAG, e.toString());
    }
    Log.d("encryptedMessage: ", encryptedMessage);
    return encryptedMessage;
}

// decrypt function
public static String decryptMessage(String privateKey, String message) {

    KeyFactory keyFactory = null;
    PrivateKey prvkey = null;
    Cipher cipher = null;

    byte[] ENCRYPTED_MESSAGE = message.getBytes();
    Log.d("ENCRYPTED_MESSAGE: ", message);

    Security.addProvider(new FlexiCoreProvider());
    Security.addProvider(new FlexiECProvider());

    try {
        // Base64 decode the privateKey string into a byte array
        byte[] decodedPrivateKey = Base64.decode(privateKey, Base64.DEFAULT);

        // instantiate a PKCS8EncodedKeySpec
        PKCS8EncodedKeySpec PKCS8spec = new PKCS8EncodedKeySpec(decodedPrivateKey);

        keyFactory = KeyFactory.getInstance("ECIES", "FlexiEC");

        // re-generate the private key
        prvkey = keyFactory.generatePrivate(PKCS8spec);

        // sanity check, return null on inequality
        if (!prvkey.equals(PrivateKey)) {
            return null;
        }

        cipher = Cipher.getInstance("ECIES", "FlexiEC");
        IESParameterSpec IESspec = new IESParameterSpec("AES256_CBC", "HmacSHA512", null, null);
        cipher.init(Cipher.DECRYPT_MODE, prvkey, IESspec);
    }
    catch (Exception e) {
        Log.e(TAG, e.toString());
    }

    // decrypt the message
    byte[] decryptedData = null;

    try {
        decryptedData = cipher.doFinal(ENCRYPTED_MESSAGE);

        // ERROR THROWN HERE! ..............................
        // de.flexiprovider.api.exceptions.BadPaddingException: invalid ciphertext
    }
    catch (IllegalBlockSizeException e) {
        Log.e(TAG, e.toString());
    }
    catch (BadPaddingException e) {
        Log.e(TAG, e.toString());
    }

    String decryptedMessage = null;

    try {
        decryptedMessage = new String(decryptedData, "UTF-8");
    }
    catch (UnsupportedEncodingException e) {
        Log.e(TAG, e.toString());
    }
    Log.d("decryptedMessage: ", decryptedMessage);
    return decryptedMessage;
}

}

推荐答案

您不能只是采用密文的输入的字符串的构造,因为你正在做这个行:

You cannot just use the cipher text as input for the String constructor, as you are doing in this line:

encryptedMessage = new String(encryptedData, "UTF-8");

您必须使用的编码,如基地64像你一样的钥匙,如果的,你想用的,而不是字节的字符串进行通信的密文的。

You will have to use an encoding such as Base 64 as you did with the keys, if you want to communicate the cipher text using strings instead of bytes.

加密将导致看似随机字节的数据。并非所有的字节有一个字符等效。的转换的结果取决于字符编码。 UTF-8可以使用许多个字节,而且许多组合不会导致正确的字符。 Java的默默的将这些,检查字符集和相关类以获取更多信息。

Encryption will result in data that looks like random bytes. Not all bytes have a character equivalent. The result of the conversion depends on the character encoding. UTF-8 may use many bytes, and many combinations won't result in correct characters. Java silently converts these, check the Charset and related classes for more information.

相关推荐