2016-07-06 11 views
1

私はスプリングセキュリティ暗号でファイル暗号化の概念の証明を作成しようとしています。 Unlimited JCE Policyをダウンロードし、java_home/jre/lib/securityフォルダにjarファイルを追加したことがわかっている他の投稿ごとに、スプリングセキュリティ暗号最終ブロックが正しく埋め込まれていない

bytesEncryptor.decryptを呼び出すときにエラーが発生します。実行後にファイルに暗号化されたコンテンツが存在するため、暗号化が機能している可能性がありますが、問題がどこにないのかを確認する方法がわかりません。このエラーについて、Springを使用していないその他の記事は、キーが正しくないと言っていますが、同じbytesEncryptorオブジェクトを使用しているため、これはできません。 (Given final block not properly padded

スタック:

Exception in thread "main" java.lang.IllegalStateException: Unable to invoke Cipher due to bad padding 
at org.springframework.security.crypto.encrypt.CipherUtils.doFinal(CipherUtils.java:142) 
    at org.springframework.security.crypto.encrypt.AesBytesEncryptor.decrypt(AesBytesEncryptor.java:128) 
    at com.test.encryption.MyTest.crypt(MyTest.java:45) 
    at com.test.encryption.MyTest.decryptFile(MyTest.java:31) 
    at com.test.encryption.MyTest.main(MyTest.java:21) 
Caused by: javax.crypto.BadPaddingException: Given final block not properly padded 
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811) 
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676) 
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313) 
    at javax.crypto.Cipher.doFinal(Cipher.java:2087) 
    at org.springframework.security.crypto.encrypt.CipherUtils.doFinal(CipherUtils.java:135) 
... 4 more 

コード:

public static void main(String args[]) throws Exception { 
    String salt = KeyGenerators.string().generateKey(); 
    BytesEncryptor bytesEncryptor = Encryptors.standard("password", salt); 

    encryptFile(bytesEncryptor, "C:/test/testIn.txt", "C:/test/testOut.txt"); 
    decryptFile(bytesEncryptor, "C:/test/testOut.txt", "C:/test/testOutDecode.txt"); 
} 


private static void encryptFile (BytesEncryptor bytesEncryptor, String in, String out) throws Exception { 
    crypt(bytesEncryptor, in, out, true); 
} 

private static void decryptFile (BytesEncryptor bytesEncryptor, String in, String out) throws Exception { 
    crypt(bytesEncryptor, in, out, false); 
} 

private static void crypt (BytesEncryptor bytesEncryptor, String in, String out, boolean encrypt) throws Exception { 
    byte[] buffer = new byte[1024]; 
    int numRead; 
    byte[] bytes = null; 
    InputStream input = new FileInputStream(in); 
    OutputStream output = new FileOutputStream(out); 

    while ((numRead = input.read(buffer)) > 0) { 
     if(encrypt) { 
      bytes = bytesEncryptor.encrypt(buffer); 
     } else { 
      bytes = bytesEncryptor.decrypt(buffer); 
     } 

     if (bytes != null) { 
      output.write(bytes, 0, numRead); 
     } 
    } 

    input.close(); 
    output.close(); 
} 

答えて

0

あなたは、FileInputStreamsとFileOutputStreamsにCipherInputStreamとCipherOutputStreamを使う必要があることが分かります。以下は

は、多かれ少なかれ、このhttp://www.programcreek.com/java-api-examples/index.php?source_dir=cube-master/cube-common/src/main/java/ch/admin/vbs/cube/common/crypto/AESEncrypter.java

更新されたコードから取られる:

import javax.crypto.*; 
import javax.crypto.spec.IvParameterSpec; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.security.SecureRandom; 

public class MyTest { 

    private static String algorithm = "AES/CBC/PKCS5Padding"; 

    public static void main(String args[]) throws Exception { 
     KeyGenerator keyGen = KeyGenerator.getInstance("AES"); 
     keyGen.init(256); 
     SecretKey secretKey = keyGen.generateKey(); 

     final int AES_KEYLENGTH = 256; 
     byte[] iv = new byte[AES_KEYLENGTH/16]; 
     SecureRandom prng = new SecureRandom(); 
     prng.nextBytes(iv); 

     Cipher aesCipherForEncryption = Cipher.getInstance(algorithm); 
     Cipher aesCipherForDecryption = Cipher.getInstance(algorithm); 
     aesCipherForEncryption.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv)); 
     aesCipherForDecryption.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv)); 

     encryptFile(aesCipherForEncryption, "C:/test/testIn.txt", "C:/test/testOut.txt"); 
     decryptFile(aesCipherForDecryption, "C:/test/testOut.txt", "C:/test/testOutDecode.txt"); 
    } 


    private static void encryptFile (Cipher cipher, String in, String out) throws Exception { 
     crypt(cipher, in, out, true); 
    } 

    private static void decryptFile (Cipher cipher, String in, String out) throws Exception { 
     crypt(cipher, in, out, false); 
    } 

    private static void crypt (Cipher cipher, String in, String out, boolean encrypt) throws Exception { 
     byte[] buffer = new byte[256]; 
     int numRead; 
     InputStream input = new FileInputStream(in); 
     OutputStream output = new FileOutputStream(out); 

     if(encrypt) { 
      output = new CipherOutputStream(output, cipher); 
     } else { 
      input = new CipherInputStream(input, cipher); 
     } 

     while ((numRead = input.read(buffer)) >= 0) { 
      output.write(buffer, 0, numRead); 
     } 

     input.close(); 
     output.close(); 
    } 
} 

注意を - 私は春のセキュリティ暗号の実装を使用してから離れていってしまっました。

0

私はこの問題は、彼らの方法あなたが1024バイトのチャンクでファイルを読み込むから来ていると思います。 AESはブロック暗号であるため、特定のサイズのデータ​​ブロックで動作します。暗号化すると、適切なサイズのチャンクに収まるように出力をパッドします。解読するデータを与えると、必要に応じて同様にデータが埋め込まれます。

ファイル全体をバイト配列に読み込み、それを暗号化して解読してみてください。また、AESに使用しているブロックサイズ(128,192,256ビット)と一致するチャンクサイズを試してみることもできます。

+0

ファイル全体を1バイト配列に読み込み、暗号化と復号化を試みましたが、同じエラーが発生しました。バッファサイズを128,196,256ビットに変更した場合も同じエラーが発生します。 SpringのAesBytesEncryptorを見ると、256ビットの暗号化を使用する必要があります。 – user1134179

関連する問題