javax.crypto.BadPaddingException : unknown block type

标签 java encryption file-io rsa java-io

我正在尝试模拟非对称 key 系统。我使用以下代码生成 key 对、加密、解密密码。我有一个分布式环境,目前我将生成的 key 保存在文件系统中。我知道这不安全,但仅用于测试目的。

    private static SecureRandom random = new SecureRandom();

    static {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    }

    protected synchronized void generateKeys() throws InvalidKeyException, IllegalBlockSizeException, 
            BadPaddingException, NoSuchAlgorithmException, NoSuchProviderException, 
                NoSuchPaddingException {

        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "BC");

        generator.initialize(256, random);

        KeyPair pair = generator.generateKeyPair();
        Key pubKey = pair.getPublic();
        Key privKey = pair.getPrivate();

        //store public key
        try {
            storeKey(pubKey, Constants.KEY_PATH.concat(Constants.SERVER_PREFIX.concat("-publickey")));
        } catch (Exception e) {
            e.printStackTrace();
            DBLogger.logMessage(e.toString(), Status.KEY_GENERATION_ERROR);
        } 

        //store private key
        try {
            storeKey(privKey, Constants.KEY_PATH.concat(Constants.SERVER_PREFIX.concat("-privatekey")));
        } catch (Exception e) {
            e.printStackTrace();
            DBLogger.logMessage(e.toString(), Status.KEY_GENERATION_ERROR);
        } 
    }

    protected synchronized String encryptUsingPublicKey(String plainText) throws IllegalBlockSizeException, BadPaddingException, 
        NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, 
            FileNotFoundException, IOException, ClassNotFoundException {

        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
        cipher.init(Cipher.ENCRYPT_MODE, readKey(Constants.KEY_PATH.concat(Constants.SERVER_PREFIX.concat("-publickey"))), random);
        byte[] cipherText = cipher.doFinal(plainText.getBytes());
        System.out.println("cipher: " + new String(cipherText));    

        return new String(cipherText);
    }

    protected synchronized String decryptUsingPrivatekey(String cipherText) throws NoSuchAlgorithmException, 
        NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, FileNotFoundException, 
            IOException, ClassNotFoundException, IllegalBlockSizeException, BadPaddingException {

        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
        cipher.init(Cipher.DECRYPT_MODE, readKey(Constants.KEY_PATH.concat(Constants.SERVER_PREFIX.concat("-privatekey"))));
        byte[] plainText = cipher.doFinal(cipherText.getBytes());
        System.out.println("plain : " + new String(plainText));

        return new String(plainText);
    }
    public static void main(String[] args) {
        KeyGenerator keyGenerator = new KeyGenerator();
        try {
            keyGenerator.deleteAllKeys(Constants.KEY_PATH);
            keyGenerator.generateKeys();

            String cipherText = keyGenerator.encryptUsingPrivateKey("dilshan");
            keyGenerator.decryptUsingPublickey(cipherText);

//          String cipherText = keyGenerator.encryptUsingPublicKey("dilshan1");
//          keyGenerator.decryptUsingPrivatekey(cipherText);
        } catch (Exception e) {
            e.printStackTrace();
            DBLogger.logMessage(e.toString(), Status.KEY_GENERATION_ERROR);
        }
    }

这在大多数情况下都运行良好。但有时它会产生以下错误。这种情况偶尔会发生。大多数时候这是有效的,所以我对代码没有问题。我相信这与文件系统的序列化/序列化过程有关。感谢帮助。

注意:我正在使用 bouncycaSTLe。

错误如下,

javax.crypto.BadPaddingException: unknown block type
    at org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineDoFinal(Unknown Source)
    at javax.crypto.Cipher.doFinal(DashoA13*..)
    at com.dilshan.ttp.web.KeyGenerator.decryptUsingPublickey(KeyGenerator.java:105)
    at com.dilshan.ttp.web.KeyGenerator.main(KeyGenerator.java:150)

发生在,

byte[] plainText = cipher.doFinal(cipherText.getBytes());

在 decryptUsingPrivatekey 方法中。

最佳答案

密文是二进制数据。如果使用默认编码将其转换为 String,很可能会遇到无法用字符表示的字节序列。因此,在解密过程中,当您将 String 转换回字节数组时,您不会得到相同的字节并且解密失败。

为了解决这个问题,不要将密文转换为字符串,而是携带 byte[]。

关于javax.crypto.BadPaddingException : unknown block type,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14109626/

相关文章:

java - 滚动后第一个项目消失后,自定义 ListView 崩溃

java - java类如何扩展另一个类并同时使用相同的方法名实现接口(interface)

c# - 从文件夹中选择随机文件

java - Spring Security 注销和最大 session 数

java - 我有正确的 XPath,但 selenium 没有在 Highcharts 弹出窗口中单击

ssl - 使用 SSL 的 IBM i DB2 JDBC 加密

java - 如何在不更改对称 key 的情况下更改非对称 key 对以及使用 Bouncy CaSTLe 的 CMS 中的加密内容

python - 使用 Flask-Security 的每个用户唯一的盐

c - fwrite 是原子的吗?

c - fopen 返回 null - Perror 打印 Invalid argument