2013-01-01 18 views
1

我試圖模擬非對稱密鑰系統。我使用以下代碼來生成密鑰對,進行加密,解密密碼。我有一個分佈式環境,目前我保存在文件系統中生成的密鑰。我知道這並不安全,但它只是用於測試目的。javax.crypto.BadPaddingException:未知塊類型

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方法

+2

除了@ Henry的評論之外,'plainText.getBytes()'這行會在將來給你帶來悲傷。它使用它運行的平臺的默認編碼。這可能會有所不同,而不是你想要的。你應該總是指定一個編碼。 「UTF-8」將始終有效,即'plainText.getBytes(「UTF-8」)'。從字節返回字符串使用'新的字符串(明文,「UTF-8」)' –

+0

確定我會修改。謝謝@GregS – Dilshan

回答

5

密文是二進制數據。如果使用默認編碼將其轉換爲String,則很可能會遇到不能由字符表示的字節序列。因此,在將String轉換回字節數組的解密過程中,最終不會得到相同的字節,並且解密失敗。

要解決這個問題,請不要將密文轉換爲字符串,而應該攜帶byte []。

+0

你是對的。問題出在方法簽名上。 decryptUsingPrivatekey(byte [] cipherText))。而不是作出是字符串我改變它爲我工作的字節數組。謝謝。 – Dilshan