2014-10-28 55 views
-1

解密XML時遇到問題,輸入我的文件返回不完整的數據算法和罕見的符號。具有大XML文件類型的不完整RSA解密 - JAVA

public File decryptFile(File fileInput, X509Certificate certificate) throws BadPaddingException, Exception { try (DataInputStream dis = new DataInputStream(new FileInputStream(fileInput))) { byte[] encryptedKeyBytes = new byte[dis.readInt()]; dis.readFully(encryptedKeyBytes); PublicKey publicKey = certificate.getPublicKey(); rsaCipher.init(Cipher.DECRYPT_MODE, publicKey); byte[] rijndaelKeyBytes = rsaCipher.doFinal(encryptedKeyBytes); SecretKey rijndaelKey = new SecretKeySpec(rijndaelKeyBytes, "Rijndael"); byte[] iv = new byte[16]; dis.read(iv); IvParameterSpec spec = new IvParameterSpec(iv); Cipher cipher = Cipher.getInstance("Rijndael/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, rijndaelKey, spec); try (CipherInputStream cis = new CipherInputStream(dis, cipher)) { try (FileOutputStream fos = new FileOutputStream(fileInput.getAbsolutePath() + ".xml")) { byte[] data = new byte[16]; int theByte; while ((theByte = cis.read(data)) != -1) { System.out.print(new String(data)); fos.write(data, 0, theByte); } System.out.println("\n\n"); } } } return new File(fileInput.getAbsolutePath() + ".xml"); }

此代碼返回我的數據

</ctaAbonBenef><distPago>00000</distPago><item>00000</item><pagoPoder>N</p�|���[�[W�Z�5��Q� 

我覺得這跟UTF-8的事,但我解決不了。

現在我也可以相信它是使用的加密算法,我爲了以防萬一。

public static void generateFileEncrypt(File fileInput, PrivateKey privateKey, String folderSave) throws Exception { String fileOutput = folderSave + "\" + fileInput.getName() + ENCRYPTED_FILENAME_SUFFIX; DataOutputStream output = new DataOutputStream(new FileOutputStream(fileOutput)); Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); rsaCipher.init(Cipher.ENCRYPT_MODE, privateKey); KeyGenerator rijndaelKeyGenerator = KeyGenerator.getInstance("Rijndael"); rijndaelKeyGenerator.init(128); Key rijndaelKey = rijndaelKeyGenerator.generateKey(); byte[] encodedKeyBytes = rsaCipher.doFinal(rijndaelKey.getEncoded()); output.writeInt(encodedKeyBytes.length); output.write(encodedKeyBytes); SecureRandom random = new SecureRandom(); byte[] iv = new byte[16]; random.nextBytes(iv); output.write(iv); IvParameterSpec spec = new IvParameterSpec(iv); Cipher symmetricCipher = Cipher.getInstance("Rijndael/CBC/PKCS5Padding"); symmetricCipher.init(Cipher.ENCRYPT_MODE, rijndaelKey, spec); try ( CipherOutputStream cos = new CipherOutputStream(output, symmetricCipher); FileInputStream fis = new FileInputStream(fileInput)) { int theByte; byte[] data = new byte[16]; while ((theByte = fis.read(data)) != -1) { System.out.print(new String(data)); cos.write(data, 0, theByte); } System.out.println("\n\n"); cos.flush(); } }

在此先感謝。

回答

1

我沒有消化所有的代碼;我停止了 我看到你試圖用公鑰解密,並用私鑰加密。這就像一個數字簽名,但你的填充將是錯誤的,你應該使用Signature類,如果這是你真正想要做的。

公鑰用於加密或驗證數字簽名。使用私鑰解密,看看是否能解決你的問題。


你還在做錯事。如果密鑰不是私密的,不要稱之爲「加密」。

但無論如何,我認爲打印到標準輸出看起來是錯誤的,因爲您正在將整個緩衝區轉換爲文本。最後一個塊可能被填充,所以它不會解碼爲有效文本—它是填充;它不是輸入文件的一部分,也不是將它寫入解密文件,而是打印它。

變化與公共密鑰加密,用私鑰解密,然後更改您的打印這樣的:

System.out.print(new String(data, 0, theByte)); 

更妙的是指定字符集的數據(可能是UTF-8 ,因爲它是XML的默認值)。

+0

我想要做的是用私鑰加密文件,就像在generateFileEncrypt方法中看到的一樣,但是用公鑰解密文件,它會返回我用奇數符號的數據。 – rodrixd 2014-10-28 19:55:46

+0

@rodrixd查看我的更新。並停止浪費無用的數學週期。 – erickson 2014-10-28 20:37:33

0

我認爲你應該做相反的事情。用公鑰加密並用私鑰解密..

+0

RSA密鑰對可以在兩個方向上進行加密。 – christopher 2014-10-28 20:17:47

+0

@christopher加密提供保密性。如果你使用公鑰,你沒有機密性,所以它不是「加密」,它不是RSA。這只是一個無用的模數求冪。 – erickson 2014-10-28 20:33:33

+0

但這裏的問題是軟件解密不正確。在數學上,這仍然應該工作。這與問題無關。我添加了這個評論,因爲如果回答者認爲使用私鑰進行加密會導致這種情況,那麼他們會錯誤的。如果他們不這樣做,那麼他們的答案就不應該成爲答案。除此之外,我同意你所說的一切。有一些使用私鑰進行加密的情況,例如用於身份驗證。 – christopher 2014-10-28 20:49:01