2011-06-26 27 views
-2

我在解密字符串时遇到了上述异常。“javax.crypto.BadPaddingException:数据必须以零开始”异常

下面是我的代码:

import java.security.KeyPair; 
import java.security.KeyPairGenerator; 
import java.security.NoSuchAlgorithmException; 
import javax.crypto.Cipher; 

public class EncryptAndDecrypt { 

    public static Cipher createCipher() throws Exception{ 

      Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 

      return cipher; 
    } 
    public static KeyPair generateKey() throws NoSuchAlgorithmException{ 

      KeyPairGenerator keyGen = KeyPairGenerator.getInstance ("RSA"); 
      keyGen.initialize(1024); 
      KeyPair key = keyGen.generateKeyPair(); 

      return key; 
    } 
    public static byte [] encrypt (String str, Cipher cip, KeyPair key) { 

     byte [] cipherText = null; 
     try { 

      byte [] plainText = str.getBytes("UTF8"); 
      cip.init(Cipher.ENCRYPT_MODE, key.getPublic()); 
      cipherText = cip.doFinal(plainText); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return cipherText; 
    } 
    public static String decrypt (byte [] c, Cipher cip, KeyPair key) throws Exception { 

     cip.init(Cipher.DECRYPT_MODE, key.getPrivate()); 

     byte [] decryptedPlainText = cip.doFinal (c);// exception occurred here 
     String decryptedPlainStr = new String (decryptedPlainText); 

     return decryptedPlainStr; 
    } 
} 


//separate class below to use the encrypt method 

public class EncryptionApp { 

    public static void main (String [] args) { 

     getEncrypted(); 
    } 
    public static byte [] getEncrypted() { 

     byte [] encyptedByte = null; 
     try { 
      String plainText = "der"; 
      Cipher cip = Safety.createCipher(); 
      KeyPair key = Safety.generateKey(); 
      encyptedByte = Safety.useRSA(plainText, cip, key); 
     } 
     catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return encyptedByte; 
    } 
} 

// Another class to use the decrypt method 

public class DecryptionApp { 

    public static void main(String[] args) { 
     System.out.println (useDecrypted()); 
    } 
    public static byte[] useDecrypted() { 

     byte [] decryptedText = null; 
     try { 
      Cipher cip = EncryptAndDecrypt.createCipher(); 
      KeyPair key = EncryptAndDecrypt.generateKey(); 
      decryptedText = EncryptAndDecrypt.decrypt(EncryptionApp.getEncrypted(),cip,key); 
     } 
     catch (Exception e) { 
      e.printStackTrace(); 
     } 
    return decryptedText; 
    } 
} 
+1

如果你不显示你的代码,没有人能够帮助你的代码。向我们展示异常堆栈跟踪,并指出代码的哪一行是发生异常的行。 –

+0

好吧,我会发布我的代码。我在想,既然有人发布过,如果我再次发布它,这将是相当多余的。 – specially

+0

Erm有关如何将密钥对存储在变量中以使其不会更改的任何想法? – 2011-07-16 10:27:40

回答

3

添加这主要方法EncryptAndDecrypt,并执行它。你会看到evrything正常工作。

public static void main(String[] args) throws Exception { 
    String s = "hello"; 
    Cipher cipher = createCipher(); 
    KeyPair keyPair = generateKey(); 
    byte[] b = encrypt(s, cipher, keyPair); 
    String s2 = decrypt(b, cipher, keyPair); 
    System.out.println(s2); 
} 

问题在于你使用这个类的方式。 的useDecrypted方法执行以下操作:

Cipher cip = EncryptAndDecrypt.createCipher(); // create a Cipher object using EncryptAndDecrypt 
KeyPair key = EncryptAndDecrypt.generateKey(); // generate a KeyPair using EncryptAndDecrypt 

// call EncryptionApp.getEncrypted() to get an encrypted text, then decrypt this encrypted text 
// using the keypair created above. 
decryptedVote = EncryptAndDecrypt.decrypt(EncryptionApp.getEncrypted(), cip, key); 

而且getEncrypted方法执行以下操作:

String plainText = "der"; // create some plain text 
// create a Cipher instance. Is it the same algorithm as the one in useDecrypted? 
// we don't know, because it uses another, unknown, Safety class 
Cipher cip = Safety.createCipher(); 
// create a new KeyPair instance. Is it the same KeyPair as the one in useDecrypted? 
// No : another keypair is generated. There is no way something encrypted using a keypair 
// will decrypt correctly with another keypair. 
KeyPair key = Safety.generateKey(); 
encyptedByte = Safety.useRSA(plainText, cip, key); 

因此,简而言之,你使用两种不同的密钥对:一个用于加密,另一个用于解密。这是行不通的。

另请注意,在encrypt中,使用UTF8编码将字符串转换为字节数组,而在decrypt中,使用默认平台编码将字节数组转换为字符串。你应该同时使用UTF8,并且因此在解密中使用以下代码:

String decryptedPlainStr = new String (decryptedPlainText, "UTF8"); 
+0

好的非常感谢帮助!但是,如果我将Safety.createCipher()更改为EncryptAndDecrypt.createCipher()和Safety.generateKey()更改为EncryptAndDecrypt.generateKey(),以使两个密钥对都相同,则同一个异常仍会发生在同一行代码中。谁能帮忙? – 2011-06-27 11:33:45

3

你是否使用过Google?当加密密钥与解密密钥不同时,很多人都会遇到这个问题。您似乎一直生成新的密钥,而不是使用相同的密钥来解密用于加密的密钥。

8

您已经在"javax.crypto.BadPaddingException: Data must start with zero" exception中提出过同样的问题,我给了您一个答案:您使用了两个不同的密钥对:一个用于加密,另一个用于解密。这是行不通的。我甚至给你提供了一个代码示例,表明如果你使用了相同的密钥对,一切都会正常运行。

KeyPairGenerator.generateKeyPair()生成密钥对。调用这个方法两次会得到两个不同的密钥对:它在内部使用一个随机数生成器来生成总是不同的密钥对。

您必须生成一次密钥对,将其存储在一个变量中,并使用该变量进行加密和解密。

您应该阅读您正在使用的类和方法的文档。 documentation of generateKeyPair说:

这将每次调用时生成一个新的密钥对 。

+0

好吧,我现在明白了。谢谢!! – specially

+0

你的意思是将KeyPair对象存储在一个变量中?或者将公钥和私钥存储在变量中?像public = keypair.getPublic(); –

+0

单个变量就足够了。但是如果你愿意,你可以使用两个。 –

0

我得到了这个错误,结果发现我的情况是我发送的base 64字符串作为参数包含一些由于在URL中而被改变的字符。该解决方案原来是URL编码参数。

相关问题