【问题标题】:RSA Decryption - BadPaddingException: Data must start with zeroRSA 解密 - BadPaddingException:数据必须从零开始
【发布时间】:2012-12-02 13:50:02
【问题描述】:

我正在编写 RSA 加密/解密。 这是代码。 但是当我使用私钥解密时,我得到了异常

public class RSACrypto {

    private static SecureRandom sr = new SecureRandom();

    /**
     * @param rsabits
     * @return keyPair
     * @throws NoSuchAlgorithmException
     */
    public static KeyPair newKeyPair(int rsabits) throws NoSuchAlgorithmException {
        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
        generator.initialize(rsabits, sr);
        return generator.generateKeyPair();
    }

    /**
     * @param key
     * @return key
     */
    public static byte[] pubKeyToBytes(PublicKey key) {
        return key.getEncoded(); // X509 for a public key
    }

    /**
     * @param key
     * @return key
     */
    public static byte[] privKeyToBytes(PrivateKey key) {
        return key.getEncoded(); // PKCS8 for a private key
    }

    /**
     * @param bytes
     * @return key
     * @throws InvalidKeySpecException
     * @throws NoSuchAlgorithmException
     */
    public static PublicKey bytesToPubKey(byte[] bytes) throws InvalidKeySpecException, NoSuchAlgorithmException {
        return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(bytes));
    }

    /**
     * @param bytes
     * @return key
     * @throws InvalidKeySpecException
     * @throws NoSuchAlgorithmException
     */
    public static PrivateKey bytesToPrivKey(byte[] bytes) throws InvalidKeySpecException, NoSuchAlgorithmException {
        return KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(bytes));
    }

    /**
     * @param input
     * @param key
     * @return encryptedText
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     * @throws InvalidKeyException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     */
    public static byte[] encryptWithPubKey(byte[] input, PublicKey key) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return cipher.doFinal(input);
    }

    /**
     * @param input
     * @param key
     * @return decryptedText
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     * @throws InvalidKeyException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     */
    public static byte[] decryptWithPrivKey(byte[] input, PrivateKey key) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, key);
        return cipher.doFinal(input);
    }

    /**
     * @param plainText
     * @return encryptedText
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     * @throws UnsupportedEncodingException
     */
    public static String encrypt(String plainText) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException,
            UnsupportedEncodingException {
        KeyPair kp = newKeyPair(1 << 11); // 2048 bit RSA; might take a second to generate keys
        PublicKey pubKey = kp.getPublic();
        PrivateKey priKey = kp.getPrivate();
        System.out.println("Private Key: " + new BASE64Encoder().encode(privKeyToBytes(priKey)));
        byte[] cipherText = encryptWithPubKey(plainText.getBytes("UTF-8"), pubKey);
        return new BASE64Encoder().encode(cipherText);
    }

    /**
     * @param encrypted
     * @param privateKey
     * @return decryptedText
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     * @throws IOException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     * @throws NoSuchPaddingException
     */
    public static String decrypt(String encrypted, String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException, InvalidKeyException, IllegalBlockSizeException,
            BadPaddingException, NoSuchPaddingException {
        PrivateKey privateKeyValue = bytesToPrivKey(new BASE64Decoder().decodeBuffer(privateKey));
        return new String(decryptWithPrivKey(new BASE64Decoder().decodeBuffer(encrypted), privateKeyValue), "UTF-8");
    }
}

我在使用生成的 privateKey 和加密文本解密时遇到错误。我浏览了很多帖子,但无法弄清楚这里出了什么问题。

javax.crypto.BadPaddingException: Data must start with zero
        at sun.security.rsa.RSAPadding.unpadV15(Unknown Source)
        at sun.security.rsa.RSAPadding.unpad(Unknown Source)
        at com.sun.crypto.provider.RSACipher.a(DashoA13*..)
        at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..)
        at javax.crypto.Cipher.doFinal(DashoA13*..)

有什么想法,请帮忙。

更新

我从不同的班级打来电话

String encryptedText = RSACrypto.encrypt("PLAIN TEXT"));

String privateKey = ""; //During encryption, it will print privatekey value, assigning the same here
String plaintext = RSACrypto.decrypt(encryptedText , privateKey);

经过一点工作,我尝试了不编码和解码Base64。它工作正常。

我在这里搞砸了 base64 什么?没有任何线索

【问题讨论】:

  • 你能把你的代码转换成一个SSCCE来证明这个问题吗?
  • 我想我已经这样做了。简单的代码没什么好看的。解密时,生成的私钥和加密文本出现错误。没有办法调试这个并最终寻求帮助。谢谢
  • 目前还不清楚你是如何一起使用各种方法的。如果您在提供的代码中添加一点main 方法,我们就可以执行该方法并看到相同的异常。 那么我们可以帮助解决您的问题。
  • 1) 考虑使用 OAEP 填充。 PKCS#1 v1.5 填充已损坏。 2)注意RSA只能加密短文本,所以你可能需要混合加密。

标签: java encryption rsa private-key


【解决方案1】:

您的复制/粘贴一定有误。我编辑了您的代码以生成不需要复制粘贴的(丑陋的)SSCCE。改变的方法是:

public static StringPair encrypt(String plainText) 
    throws GeneralSecurityException, UnsupportedEncodingException {

  // Note: this is a very confusing way to say 2048
  KeyPair kp = newKeyPair(1 << 11); 

  PublicKey pubKey = kp.getPublic();
  PrivateKey priKey = kp.getPrivate();
  byte[] cipherText = encryptWithPubKey(plainText.getBytes("UTF-8"), pubKey);

  // Here I return both items, to remove copy/paste problems
  StringPair result = new StringPair();
  result.encryptedText = new BASE64Encoder().encode(cipherText);
  result.key = new BASE64Encoder().encode(privKeyToBytes(priKey));
  return result;
}


private static class StringPair {
  public String encryptedText;
  public String key;
}


public static void main(String[] args) throws Exception {
  StringPair result = RSACrypto.encrypt("PLAIN TEXT");    
  System.out.println(RSACrypto.decrypt(result.encryptedText, result.key));       
}  

这会打印出PLAIN TEXT

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-14
    • 2014-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    • 2011-09-03
    相关资源
    最近更新 更多