2016-07-15 31 views
11

Tôi có một số văn bản được mã hóa và lưu trữ trong một db sử dụng PBE AES_256. Điều này ban đầu được thực hiện bằng cách sử dụng java 1.8.0_65. Sau khi nâng cấp lên java mới nhất, tôi không còn có thể giải mã các trường này nữa. Tôi đã xác định sự không tương thích với 1.8.0_71. Các ghi chú phát hành nêu như sau:Mã hóa PBE AES_256 không tương thích giữa java 8 u65 và u71

Vấn đề với các thuật toán PBE sử dụng AES crypto chỉnh Một lỗi đã được sửa chữa cho PBE sử dụng 256-bit AES thuật toán mã hóa như vậy mà quan trọng có nguồn gốc có thể khác nhau và không tương đương với các phím trước đây có nguồn gốc từ cùng một mật khẩu. JDK-8.138.589 (không được công khai)

Vì vậy, tôi cho rằng tôi cần phải di chuyển 'bằng tay' những giá trị trường, bởi giải mã với phiên bản cũ, lưu trữ các giá trị đơn giản và sau đó tái mã hóa với phiên bản hiện tại. Có cách nào tốt hơn để làm điều đó hoặc tôi có lẽ thiếu một cái gì đó liên quan đến sự không tương thích này?

Đây là một phần của mã được sử dụng để mã hóa:

SecretKey keyFromPassword = 
     SecretKeyFactory.getInstance(
      algorithm).generateSecret(
      new PBEKeySpec(password.toCharArray())); 

Cipher cipher = Cipher.getInstance(algorithm); 
cipher.init(Cipher.ENCRYPT_MODE, keyFromPassword, new PBEParameterSpec(
     salt, iterations, new IvParameterSpec(iv))); 
IOUtils.copyLarge(new CipherInputStream(clearStream, cipher), encryptedStream); 

Giải pháp tôi đã có thể giải mã các giá trị hiện tại bằng cách thực hiện một số phản ánh kỳ diệu về cơ yếu và tôi tái khởi tạo nó. Dưới đây là mã nếu có ai quan tâm:

Object spi = ReflectionTestUtils.getField(cipher, "spi"); 
ReflectionTestUtils.setField(spi, "keyLength", 128); 
cipher.init(Cipher.DECRYPT_MODE, keyFromPassword, new PBEParameterSpec(
     salt, iterations, new IvParameterSpec(iv))); 
+0

sẽ tốt hơn nếu bạn đăng giải pháp của mình làm câu trả lời – spirit

Trả lời

4

Di chuyển giá trị trường giống như cách tiếp cận hợp lý.

Nhìn vào actual code change liên quan đến JDK-8138589 không quá phức tạp.

Sự khác biệt có vẻ chỉ là độ dài khóa. Do đó bạn sẽ có thể tạo lại giá trị cũ ngay cả trên các phiên bản sau 1.8.0_71.

Trong trường hợp bạn phát hiện một giá trị được tạo bằng phiên bản Java cũ nhưng hiện đang chạy trên phiên bản Java "mới", bạn có thể di chuyển nó. Việc di chuyển thành công được biểu thị bằng và trường bổ sung được lưu.

+0

Cảm ơn. Tôi không chắc chắn cách tạo lại giá trị cũ trên phiên bản 71+. Tôi có thể tự thiết lập keyLength trong 'PBEParameterSpec' không? – kpentchev

+0

Bạn chưa cung cấp mã như thế nào bạn mã hóa do đó tôi không biết bạn đang sử dụng mã nào. Tôi giả sử bạn phải tự tạo khóa và en/decrypt. Xem [PBES2Core.java] (http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/5ea62bb625b6/src/share/classes/com/sun/crypto/provider/PBES2Core.java) để biết chi tiết. – Robert

+0

Cảm ơn, tôi đã xem xét nó. Tôi cũng sẽ cung cấp một đoạn mã trong câu hỏi ban đầu. – kpentchev

Các vấn đề liên quan