Bảo mật Java: Kích thước khóa bất hợp pháp hoặc tham số mặc định?


409

Tôi đã hỏi một câu hỏi về điều này sớm hơn, nhưng nó không được trả lời đúng và không dẫn đến đâu.

Vì vậy, tôi đã làm rõ một vài chi tiết về vấn đề này và tôi thực sự muốn nghe ý kiến ​​của bạn về cách tôi có thể khắc phục vấn đề này hoặc tôi nên thử điều gì.

Tôi đã cài đặt Java 1.6.0.12 trên máy chủ Linux của mình và đoạn mã bên dưới chạy hoàn hảo.

String key = "av45k1pfb024xa3bl359vsb4esortvks74sksr5oy4s5serondry84jsrryuhsr5ys49y5seri5shrdliheuirdygliurguiy5ru";
try {
    Cipher c = Cipher.getInstance("ARCFOUR");

    SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "ARCFOUR");
    c.init(Cipher.DECRYPT_MODE, secretKeySpec);

    return new String(c.doFinal(Hex.decodeHex(data.toCharArray())), "UTF-8");

} catch (InvalidKeyException e) {
    throw new CryptoException(e);
}

Hôm nay tôi đã cài đặt Java 1.6.0.26 trên người dùng máy chủ của mình và khi tôi thử chạy ứng dụng của mình, tôi gặp ngoại lệ sau. Tôi đoán là nó có liên quan đến cấu hình cài đặt Java vì nó hoạt động trong phiên bản đầu tiên, nhưng không hoạt động trong phiên bản sau.

Caused by: java.security.InvalidKeyException: Illegal key size or default parameters
    at javax.crypto.Cipher.a(DashoA13*..) ~[na:1.6]
    at javax.crypto.Cipher.a(DashoA13*..) ~[na:1.6]
    at javax.crypto.Cipher.a(DashoA13*..) ~[na:1.6]
    at javax.crypto.Cipher.init(DashoA13*..) ~[na:1.6]
    at javax.crypto.Cipher.init(DashoA13*..) ~[na:1.6]
    at my.package.Something.decode(RC4Decoder.java:25) ~[my.package.jar:na]
    ... 5 common frames omitted

Dòng 25 là: c.init(Cipher.DECRYPT_MODE, secretKeySpec);

Lưu ý:
* java.security trên thư mục java 1.6.0.12 của máy chủ khớp gần như hoàn toàn với tệp java.security 1.6.0.26 . Không có nhà cung cấp bổ sung trong cái đầu tiên.
* Câu hỏi trước đây là đây .



4
Điều này cũng có thể bị ném là lỗi: Caused by: java.security.InvalidKeyException: Illegal key size(không có "hoặc tham số mặc định") trong Java 8
hackajar

Chỉ cần sử dụng OpenJDK và nó sẽ hoạt động.
Rodrigo Asensio

@RodrigoAsensio: Tôi đang sử dụng OpenJDK và nó không hoạt động với nó. Bạn phải cài đặt các tệp jar Chính sách Thẩm quyền Sức mạnh không giới hạn. Và sau đó nó sẽ hoạt động.
anjanb

5
Cập nhật câu trả lời @AniketThakur. Vì Java 9 và Java 8u151, không cần phải tải xuống và cài đặt thủ công các tệp chính sách quyền tài phán nữa. Để kích hoạt mật mã không giới hạn, người ta có thể sử dụng thuộc tính Bảo mật crypto.policy mới. Nếu thuộc tính Bảo mật mới (crypto.policy) được đặt trong tệp java.security hoặc đã được đặt tự động bằng cách sử dụng lệnh gọi Security.setProperty () trước khi khung JCE được khởi tạo, cài đặt đó sẽ được thực hiện. Theo mặc định, tài sản sẽ không được xác định.
Marcin Kłopotek

Câu trả lời:


722

Nhiều khả năng bạn không có tệp sức mạnh không giới hạn được cài đặt ngay bây giờ.

Bạn có thể cần phải tải xuống tệp này:

Phần mở rộng mã hóa Java (JCE) Chính sách tài phán về sức mạnh không giới hạn 6

Phần mở rộng mã hóa Java (JCE) Chính sách quyền lực không giới hạn 7 Tải xuống

Phần mở rộng mã hóa Java (JCE) Chính sách tài phán về sức mạnh không giới hạn 8 Tải xuống (chỉ yêu cầu cho các phiên bản trước Java 8 u162)

Giải nén các tệp jar từ zip và lưu chúng vào ${java.home}/jre/lib/security/.


2
@JamesBlack - Yep, và để đảm bảo tất cả các căn cứ được bao phủ Tôi đặt dưới của JAR Java/jre/lib/security, Java/jdk/lib/securityJava/jdk/jre/lib/security. Chạy 'java -version' trả về các chi tiết dự kiến.
aroth

5
Đối với SDK của IBM (ví dụ: WebSphere), tải xuống các tệp chính sách quyền tài phán không giới hạn từ www14.software.ibm.com/webapp/iwm/web/preLogin.do?source=jcesdk
quietmint 27/12/13

4
Vì Java 9 và Java 8u151, không cần phải tải xuống và cài đặt thủ công các tệp chính sách quyền tài phán nữa. Để kích hoạt mật mã không giới hạn, người ta có thể sử dụng thuộc tính Bảo mật crypto.policy mới. Nếu thuộc tính Bảo mật mới (crypto.policy) được đặt trong tệp java.security hoặc đã được đặt tự động bằng cách sử dụng lệnh gọi Security.setProperty () trước khi khung JCE được khởi tạo, cài đặt đó sẽ được thực hiện. Theo mặc định, tài sản sẽ không được xác định.
Marcin Kłopotek

4
Vì vậy, câu trả lời nâng cao này hiện đã lỗi thời và không được dùng nữa. Làm thế nào để chúng tôi nâng cấp hoặc thay thế câu trả lời này để stackoverflow.com/a/46857694/2808798 có thể là câu trả lời "được chấp nhận"?
Jesse Adelman

3
@JesseAdelman - Thật không may, điều này đã gần 7 tuổi, không thể làm được gì nhiều. Bất cứ ai hỏi sẽ cần phải thay đổi nó.
James Black

54

Các tệp thẩm quyền JRE / JDK / Java 8 có thể được tìm thấy ở đây:

Phần mở rộng chính sách thẩm quyền mã hóa Java (JCE) không giới hạn 8 tệp

Giống như James đã nói ở trên:
Cài đặt các tập tin trong ${java.home}/jre/lib/security/.


2
Đã thử sử dụng 6 và 7, nhưng chúng không hoạt động. Phải cài đặt 8. Cảm ơn.
Jason Kim

9
Bản phát hành mới JDK 8u151 có "Thuộc tính bảo mật mới để kiểm soát chính sách tiền điện tử". Bây giờ là một sự thay đổi thuộc tính để chuyển đổi. Dòng dưới cùng: xóa "#" khỏi dòng "# crypto.policy = không giới hạn" trong "lib \ security \ java.security" để cho phép sử dụng các khóa 256 bit. oracle.com/technetwork/java/javase/8u151-relnotes-3850493.html
hemisphin

1
Cảm ơn! Vì đây là thuộc tính bảo mật, bạn cũng có thể gọi Security.setProperty ("crypto.policy", "không giới hạn"). Nguồn: liên kết của
@hemiserald

42

Đối với JAVA 7, liên kết tải xuống là jce-7-download

Sao chép hai lọ đã tải xuống trong Java \ jdk1.7.0_10 \ jre \ lib \ security
Sao lưu các lọ cũ hơn để ở bên an toàn hơn.

Đối với JAVA 8, liên kết tải xuống là jce-8-download
Sao chép các tệp đã tải xuống trong Java \ jdk1.8.0_45 \ jre \ lib \ security
Sao lưu các lọ cũ hơn để an toàn hơn.


39

Với Java 9, Java 8u161 , Java 7u171Java 6u181 , giới hạn hiện bị tắt theo mặc định. Xem sự cố trong Cơ sở dữ liệu lỗi Java .


Bắt đầu với Java 8u151, bạn có thể vô hiệu hóa giới hạn theo chương trình.

Trong các bản phát hành cũ hơn, các tệp quyền hạn của JCE phải được tải xuống và cài đặt riêng để cho phép mã hóa không giới hạn được sử dụng bởi JDK. Các bước tải xuống và cài đặt không còn cần thiết.

Thay vào đó, bây giờ bạn có thể gọi dòng sau trước khi sử dụng các lớp JCE đầu tiên (tốt nhất là ngay sau khi bắt đầu ứng dụng):

Security.setProperty("crypto.policy", "unlimited");

Còn về Android thì sao? Ở cấp độ API nào các phương pháp hạn chế này có thể được giải quyết?
TheRealChx101

31

Đây là một giải pháp chỉ mã . Không cần phải tải xuống hoặc gây rối với các tập tin cấu hình.

Đó là một giải pháp dựa trên sự phản chiếu, được thử nghiệm trên java 8

Gọi phương pháp này một lần, sớm trong chương trình của bạn.

// Nhập khẩu

import javax.crypto.Cipher;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Map;

//phương pháp

public static void fixKeyLength() {
    String errorString = "Failed manually overriding key-length permissions.";
    int newMaxKeyLength;
    try {
        if ((newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES")) < 256) {
            Class c = Class.forName("javax.crypto.CryptoAllPermissionCollection");
            Constructor con = c.getDeclaredConstructor();
            con.setAccessible(true);
            Object allPermissionCollection = con.newInstance();
            Field f = c.getDeclaredField("all_allowed");
            f.setAccessible(true);
            f.setBoolean(allPermissionCollection, true);

            c = Class.forName("javax.crypto.CryptoPermissions");
            con = c.getDeclaredConstructor();
            con.setAccessible(true);
            Object allPermissions = con.newInstance();
            f = c.getDeclaredField("perms");
            f.setAccessible(true);
            ((Map) f.get(allPermissions)).put("*", allPermissionCollection);

            c = Class.forName("javax.crypto.JceSecurityManager");
            f = c.getDeclaredField("defaultPolicy");
            f.setAccessible(true);
            Field mf = Field.class.getDeclaredField("modifiers");
            mf.setAccessible(true);
            mf.setInt(f, f.getModifiers() & ~Modifier.FINAL);
            f.set(null, allPermissions);

            newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES");
        }
    } catch (Exception e) {
        throw new RuntimeException(errorString, e);
    }
    if (newMaxKeyLength < 256)
        throw new RuntimeException(errorString); // hack failed
}

Tín dụng: Delthas


4
Xin lưu ý rằng điều này có thể vi phạm thỏa thuận cấp phép Java SE: D. GIỚI HẠN CÔNG NGHỆ JAVA. Bạn không được tạo, sửa đổi hoặc thay đổi hành vi hoặc ủy quyền cho người được cấp phép của bạn để tạo, sửa đổi hoặc thay đổi hành vi của các lớp, giao diện hoặc gói con theo bất kỳ cách nào được xác định là "java", "javax", " javafx "," mặt trời ", Nhật Bản hay hội nghị tương tự như quy định của Oracle trong bất kỳ chỉ định quy ước đặt tên nào. [...] nguồn
SimMac

Cảm ơn bạn rất nhiều


16

Tôi đã gặp lỗi tương tự khi sử dụng Windows 7 x64, Eclipse và JDK 1.6.0_30. Trong thư mục cài đặt JDK có một jrethư mục. Điều này đã ném tôi lúc đầu khi tôi thêm các lọ đã nói ở trên vào thư mục lib / security của JDK mà không gặp may. Đường dẫn đầy đủ:

C:\Program Files\Java\jdk1.6.0_30\jre\lib\security

Tải xuống và giải nén các tập tin có trong jcethư mục của kho lưu trữ này vào thư mục đó.


16

Trong Java, theo mặc định, AES hỗ trợ khóa 128 Bit, nếu bạn dự định sử dụng khóa 192 Bit hoặc 256 Bit, trình biên dịch java sẽ ném Ngoại lệ kích thước khóa bất hợp pháp mà bạn đang nhận.

Giải pháp là như người chiến thắng & James đề xuất, bạn sẽ cần tải xuống JCE (Java Cryptography Extension) theo phiên bản JRE của bạn, (java6, java7 hoặc java8).

Mã khóa JCE chứa JAR sau:

  1. local_policy.jar
  2. US_export_policy.jar

Bạn cần phải thay thế các hình thức jar của bạn <JAVA_HOME>/jre/lib/security. nếu bạn đang sử dụng hệ thống unix, có lẽ bạn sẽ tham khảo/home/urs/usr/lib/jvm/java-<version>-oracle/

Đôi khi, chỉ cần thay thế local_policy.jar, US_export_policy.jar trong thư mục bảo mật không hoạt động trên unix, vì vậy tôi khuyên bạn nên sao chép thư mục bảo mật vào máy tính để bàn trước, thay thế thư mục @ Desktop / security của jar, xóa thư mục bảo mật khỏi / jre / lib / & di chuyển thư mục bảo mật Desktop sang / jre / lib /.

ví dụ :: bảo mật sudo mv /usr/lib/jvm/java-7-oracle/jre/lib


5

Có một cuộc thảo luận ngắn về những gì dường như là vấn đề này ở đây . Trang mà nó liên kết dường như không còn nữa, nhưng một trong những phản hồi có thể là những gì bạn cần:

Thật vậy, sao chép US_export_policy.jar và local_policy.jar từ core / lib / jce sang $ JAVA_HOME / jre / lib / security. Cảm ơn.


Cảm ơn, nhưng tôi đã có US_export_policy.jarlocal_policy.jartrong thư mục lib / security của mình khi tôi cài đặt Java .. Và tôi không thể tìm thấy core / lib / jce trong thư mục cài đặt Java của mình.
Rihards

5

vấn đề là nội dung của tệp default_local.policy trong local_policy.jar trong thư mục jre \ lib \ security , nếu bạn cài đặt JRE:

// Some countries have import limits on crypto strength. This policy file
// is worldwide importable.

grant {
    permission javax.crypto.CryptoPermission "DES", 64;
    permission javax.crypto.CryptoPermission "DESede", *;
    permission javax.crypto.CryptoPermission "RC2", 128,
                                     "javax.crypto.spec.RC2ParameterSpec", 128;
    permission javax.crypto.CryptoPermission "RC4", 128;
    permission javax.crypto.CryptoPermission "RC5", 128,
          "javax.crypto.spec.RC5ParameterSpec", *, 12, *;
    permission javax.crypto.CryptoPermission "RSA", *;
    permission javax.crypto.CryptoPermission *, 128;
};

nếu bạn không cần cài đặt hợp lệ trên toàn thế giới, bạn chỉ cần chỉnh sửa tệp này và thay đổi nội dung thành

// Country-specific policy file for countries with no limits on crypto strength.
grant {
    // There is no restriction to any algorithms.
    permission javax.crypto.CryptoAllPermission;
};

đây là những gì nhận được nếu bạn tải xuống JCE từ Oracle.


4

Tôi cũng đã gặp sự cố nhưng sau khi thay thế sự cố hiện tại bằng tải xuống (từ JCE), người ta đã giải quyết vấn đề. Các tập tin mật mã mới cung cấp sức mạnh không giới hạn.


2

Theo mặc định, Java chỉ hỗ trợ kích thước khóa AES 128 bit (16 byte) để mã hóa. Nếu bạn không cần nhiều hơn mặc định được hỗ trợ, bạn có thể cắt phím theo kích thước phù hợp trước khi sử dụng Cipher. Xem javadoc cho các khóa được hỗ trợ mặc định.

Đây là một ví dụ về việc tạo khóa sẽ hoạt động với bất kỳ phiên bản JVM nào mà không sửa đổi các tệp chính sách. Sử dụng theo quyết định của riêng bạn.

Đây là một bài viết hay về việc liệu kích thước khóa 128 đến 256 có quan trọng trên Blog AgileBits

SecretKeySpec getKey() {
    final pass = "47e7717f0f37ee72cb226278279aebef".getBytes("UTF-8");
    final sha = MessageDigest.getInstance("SHA-256");

    def key = sha.digest(pass);
    // use only first 128 bit (16 bytes). By default Java only supports AES 128 bit key sizes for encryption.
    // Updated jvm policies are required for 256 bit.
    key = Arrays.copyOf(key, 16);
    return new SecretKeySpec(key, AES);
}

Các Cipher điểm lớp tài liệu kích thước khóa hợp lệ đối với từng loại crypto.
keaplogik

Xem Thuật toán mã hóa tài liệu Oracle (Mã hóa) AES: Tiêu chuẩn mã hóa nâng cao theo quy định của NIST trong Trin 197. Còn được gọi là thuật toán Rijndael của Joan Daemen và Vincent Rijmen, AES là một mật mã khối 128 bit hỗ trợ các khóa 128, 192, và 256 bit.
zaph

Điều đó có thể đúng, nhưng mỗi phiên bản Java chỉ yêu cầu hỗ trợ 128 bit như được chỉ định trong tài liệu lớp. Tự kiểm tra và bạn sẽ thấy bạn sẽ cần bình chính sách từ câu trả lời của James Black để thực hiện các kích thước chính khác
keaplogik

Bất kỳ triển khai AES nào không hỗ trợ khóa 256 bit về cơ bản sẽ vô dụng vì nó sẽ không thể giải mã được số lượng lớn mã hóa AES bằng khóa 256 bit.
zaph

1
Nếu khóa 256 bit là giải pháp tốt nhất, có lẽ là giải pháp duy nhất, là cài đặt tệp Chính sách nếu cần, không cắt ngắn khóa có khả năng làm suy yếu bảo mật và có thể không thực hiện được trong trường hợp có khả năng tương tác.
zaph

2

Bắt đầu từ Java 9 hoặc 8u151, bạn có thể sử dụng nhận xét một dòng trong tệp:

<JAVA_HOME>/jre/lib/security/java.security

Và thay đổi:

#crypto.policy=unlimited

đến

crypto.policy=unlimited

2

Nếu bạn đang sử dụng phân phối Linux với apt và đã thêm webupd8 PPA, bạn chỉ cần chạy lệnh

apt-get install oracle-java8-unlimited-jce-policy

Các cập nhật khác:

  1. Các tệp chính sách quyền tài phán cường độ không giới hạn được bao gồm trong Java 9 và được sử dụng theo mặc định
  2. Bắt đầu với Java 8 Update 161 , Java 8 mặc định là Chính sách quyền lực không giới hạn.
  3. Bắt đầu với Java 8 Update 151 , Chính sách quyền hạn không giới hạn được bao gồm trong Java 8 nhưng không được sử dụng theo mặc định. Để kích hoạt nó, bạn cần chỉnh sửa tệp java.security trong <java_home>/jre/lib/security(đối với JDK) hoặc <java_home>/lib/security(đối với JRE). Uncomment (hoặc bao gồm) dòng

    crypto.policy=unlimited

    Hãy chắc chắn rằng bạn chỉnh sửa tệp bằng trình chỉnh sửa chạy với tư cách quản trị viên. Thay đổi chính sách chỉ có hiệu lực sau khi khởi động lại JVM

Trước khi cập nhật Java 8, 151 câu trả lời còn lại hợp lệ. Tải xuống tập tin chính sách thẩm quyền không giới hạn sức mạnh của JCE và thay thế.

Để biết thêm chi tiết, bạn có thể tham khảo bài đăng trên blog cá nhân của tôi bên dưới - Cách cài đặt các tệp chính sách tài phán về sức mạnh không giới hạn của Mã hóa Java (JCE)


1

Có hai lựa chọn để giải quyết vấn đề này

tùy chọn số 1: sử dụng chứng chỉ có độ dài ít hơn RSA 2048

tùy chọn số 2: bạn sẽ cập nhật hai lọ trong jre\lib\security bất cứ thứ gì bạn sử dụng java http://www.oracle.com/technetwork/java/javase/doads/jce-6-doad-429243.html

hoặc bạn sử dụng websphere của IBM hoặc bất kỳ máy chủ ứng dụng nào sử dụng java của nó. vấn đề chính mà tôi gặp phải là tôi đã sử dụng chứng nhận với độ dài tối đa, khi tôi triển khai đôi tai trên websphere, ngoại lệ tương tự được đưa ra

Java Security: Illegal key size or default parameters?

tôi đã cập nhật thư mục intsalled java trong websphere với hai tệp https://www14.software.ibm.com/webapp/iwm/web/reg/pick.do?source=jcesdk&lang=en_US

bạn có thể kiểm tra tài liệu tham khảo trong liên kết https://www-01.ibm.com/support/docview.wss?uid=swg21663373


1

Hãy chắc chắn rằng bạn sử dụng phiên bản mới nhất của JDK / JRE .

Trong trường hợp của tôi, tôi đã đặt JCE vào thư mục JRE, nhưng nó không giúp được gì. Nó xảy ra bởi vì tôi đang chạy dự án của tôi trực tiếp từ IDE (sử dụng JDK).

Sau đó, tôi đã cập nhật JDK và JRE của mình lên phiên bản mới nhất (1.8.0_211) và vấn đề đã biến mất.

Thêm chi tiết: https://bugs.java.com/bugdatabase/view_orms.do?orms_id=JDK-8170157


1

JDK mặc định chỉ hỗ trợ mã hóa thông qua các khóa 128 bit vì các hạn chế của Mỹ. Vì vậy, để hỗ trợ mã hóa từ khóa dài 256 bit, chúng ta phải thay thế local_policy.jarUS_export_policy.jarstrong $JAVA_HOME/java-8-oracle/jre/lib/securitythư mục nếu không nó sẽ cung cấp:

java.security.InvalidKeyException: Kích thước khóa bất hợp pháp hoặc mặc định


0

Bạn cần phải đến đó

/jdk1.8.0_152 | / jre | / lib | / bảo mật | java.securance và uncomment

#crypto.policy=unlimited

đến

crypto.policy=unlimited
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.