2011-06-26 24 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編碼參數。

相關問題