Java 보안 : 잘못된 키 크기 또는 기본 매개 변수?


409

나는 이것에 대해 이전에 질문을했지만, 제대로 대답하지 못했으며 아무데도 주도하지 못했습니다.

문제에 대한 몇 가지 세부 사항을 명확히 했으므로 어떻게 해결할 수 있는지 또는 무엇을 시도 해야하는지에 대한 아이디어를 듣고 싶습니다.

내가 가진 자바 1.6.0.12이 내 리눅스 서버와 바로 완벽하게 실행 아래의 코드에 설치되어 있어야합니다.

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);
}

오늘은 서버 사용자에게 Java 1.6.0.26 을 설치 했으며 응용 프로그램을 실행하려고하면 다음 예외가 발생합니다. 제 생각에는 Java 설치 구성과 관련이 있지만 첫 번째 버전에서는 작동하지만 이후 버전에서는 작동하지 않기 때문입니다.

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

25 행 : c.init(Cipher.DECRYPT_MODE, secretKeySpec);

참고 :
* 서버 1.6.0.12 java 디렉토리의 java.security 는 1.6.0.26 java.security 파일 과 거의 완전히 일치 합니다. 첫 번째 공급자에는 추가 공급자가 없습니다.
* 이전 질문은 여기에 있습니다 .



4
이것은 또한 오류로 발생 될 수있다 Caused by: java.security.InvalidKeyException: Illegal key size(이하 "또는 기본 매개 변수"없이) 자바 8
hackajar

OpenJDK를 사용하면 작동합니다.
로드리고 아센시 오

@RodrigoAsensio : OpenJDK를 사용하고 있으며 작동하지 않습니다. 무제한 강도 관할 정책 파일 jar 파일을 설치해야합니다. 그런 다음 작동합니다.
anjanb

5
@AniketThakur 답변으로 업데이트하십시오. Java 9 및 Java 8u151 이후 더 이상 관할 정책 파일을 다운로드하여 수동으로 설치할 필요가 없습니다. 무제한 암호화를 사용하려면 새로운 crypto.policy Security 속성을 사용할 수 있습니다. 새 보안 특성 (crypto.policy)이 java.security 파일에 설정되었거나 JCE 프레임 워크가 초기화되기 전에 Security.setProperty () 호출을 사용하여 동적으로 설정된 경우 해당 설정이 적용됩니다. 기본적으로 속성은 정의되지 않습니다.
Marcin Kłopotek

답변:


722

현재 무제한 강도 파일이 설치되어 있지 않을 가능성이 큽니다.

이 파일을 다운로드해야 할 수도 있습니다.

JCE (Java Cryptography Extension) 무제한 강도 관할 정책 파일 6

JCE (Java Cryptography Extension) 무제한 강도 관할 정책 파일 7 다운로드

JCE (Java Cryptography Extension) 무제한 강도 관할 정책 파일 8 다운로드 (Java 8 u162 이전 버전에만 필요)

zip에서 jar 파일을 추출하여에 저장하십시오 ${java.home}/jre/lib/security/.


2
@JamesBlack - 그래, 있는지 모든 기반이 나는 JAR의 아래를 넣어 덮여 있었다 만들기 위해 Java/jre/lib/security, Java/jdk/lib/security그리고 Java/jdk/jre/lib/security. 'java -version'을 실행하면 예상되는 세부 사항이 리턴됩니다.
aroth


4
Java 9 및 Java 8u151 이후 더 이상 관할 정책 파일을 다운로드하여 수동으로 설치할 필요가 없습니다. 무제한 암호화를 사용하려면 새로운 crypto.policy Security 속성을 사용할 수 있습니다. 새 보안 특성 (crypto.policy)이 java.security 파일에 설정되었거나 JCE 프레임 워크가 초기화되기 전에 Security.setProperty () 호출을 사용하여 동적으로 설정된 경우 해당 설정이 적용됩니다. 기본적으로이 속성은 정의되어 있지 않습니다.
Marcin Kłopotek

4
따라서이 공감 된 답변은 이제 구식이며 더 이상 사용되지 않습니다. stackoverflow.com/a/46857694/2808798 이 "허용되는"답변이 될 수 있도록이 답변을 어떻게 찬성 또는 억제 합니까?
Jesse Adelman

3
@JesseAdelman-불행히도 이것은 거의 7 세이며 많은 것을 할 수 없습니다. 요청한 사람은 변경해야합니다.
James Black

54

JRE / JDK / Java 8 관할권 파일은 여기에서 찾을 수 있습니다.

JCE (Java Cryptography Extension) 무제한 강도 관할 정책 파일 8 다운로드

James가 위에서 말한 것처럼 :
에 파일을 설치하십시오 ${java.home}/jre/lib/security/.


2
6과 7을 사용하려고 시도했지만 작동하지 않았습니다. 8을 설치했습니다. 감사합니다.
Jason Kim

9
새로운 릴리스 JDK 8u151에는 "암호화 정책을 제어하는 ​​새로운 보안 속성"이 있습니다. 이제 전환 할 속성 변경입니다. 결론 : 256 비트 키를 사용하려면 "lib \ security \ java.security"의 "# crypto.policy = unlimited"줄에서 "#"을 제거하십시오. oracle.com/technetwork/java/javase/8u151-relnotes-3850493.html
hemisphire

1
감사! 이것은 보안 특성이므로 Security.setProperty ( "crypto.policy", "unlimited")를 호출 할 수도 있습니다. 출처 : @hemisphire의 링크 :)
Fluf

42

JAVA 7의 경우 다운로드 링크는 jce-7-download입니다.

Java \ jdk1.7.0_10 \ jre \ lib \ security에 다운로드 된 두 jar를 복사하십시오
.

JAVA 8의 경우 다운로드 링크는 jce-8-download입니다
. 다운로드 된 jar 파일을 Java \ jdk1.8.0_45 \ jre \ lib \ security에 복사
하십시오. 이전 jar 파일을 더 안전하게 백업하십시오.


39

Java 9, Java 8u161 , Java 7u171Java 6u181 에서는 기본적 으로이 제한이 비활성화되어 있습니다. Java 버그 데이터베이스의 문제를 참조하십시오 .


Java 8u151 부터는 프로그래밍 방식으로 제한을 비활성화 할 수 있습니다.

이전 릴리스에서는 JDK에서 무제한 암호화를 사용할 수 있도록 JCE 관할권 파일을 별도로 다운로드하여 설치해야했습니다. 더 이상 다운로드 및 설치 단계가 필요하지 않습니다.

대신 JCE 클래스를 처음 사용하기 전에 (즉, 응용 프로그램을 시작한 직후) 다음 줄을 호출 할 수 있습니다.

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

안드로이드는 어떻습니까? 이러한 제한 방법을 어느 API 수준에서 해결할 수 있습니까?
TheRealChx101

31

이것은 코드 전용 솔루션 입니다. 구성 파일을 다운로드하거나 엉망으로 만들 필요가 없습니다.

Java 8 에서 테스트 된 리플렉션 기반 솔루션입니다.

프로그램 초기에이 메소드를 한 번 호출하십시오.

// 수입

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

//방법

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
}

크레딧 : Delthas


4
이는 Java SE 라이센스 계약을 위반할 수 있습니다. D. JAVA 기술 제한. 귀하는 "java", "javax", "" javafx ","sun ","oracle "또는 기타 명명 규칙 지정에서 Oracle에 의해 지정된 유사한 규칙. [...] source
SimMac

정말 감사합니다


16

Windows 7 x64, Eclipse 및 JDK 1.6.0_30을 사용하는 동안 동일한 오류가 발생했습니다. JDK 설치 폴더에는 jre폴더가 있습니다. 앞서 언급 한 항아리를 JDK의 lib / security 폴더에 운없이 추가하면서 처음에는 나를 버렸습니다. 전체 경로 :

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

이 아카이브jce 폴더에 포함 된 파일을 다운로드 하여 해당 폴더로 추출하십시오 .


16

Java에서 기본적으로 AES는 128 비트 키를 지원합니다. 192 비트 또는 256 비트 키를 사용하려는 경우 java complier는 잘못된 키 크기 예외를 발생시킵니다.

해결책은 victor & James가 제안한 것처럼 JRE 버전 (java6, java7 또는 java8)에 따라 JCE (Java Cryptography Extension)를 다운로드해야합니다.

JCE zip에는 다음 JAR이 포함되어 있습니다.

  1. local_policy.jar
  2. US_export_policy.jar

이 항아리를 교체해야합니다 <JAVA_HOME>/jre/lib/security. 유닉스 시스템을 사용하고 있다면 아마도/home/urs/usr/lib/jvm/java-<version>-oracle/

때로는 보안 폴더의 local_policy.jar, US_export_policy.jar를 유닉스에서 작동하지 않기 때문에 먼저 보안 폴더를 데스크탑에 복사하고 jar의 @ Desktop / security 폴더를 바꾸고 / jre / lib에서 보안 폴더를 삭제하는 것이 좋습니다 / 및 데스크탑 보안 폴더를 / jre / lib /로 이동하십시오.

예 :: sudo mv security /usr/lib/jvm/java-7-oracle/jre/lib


5

여기 에서이 문제로 보이는 것에 대한 간단한 설명이 있습니다 . 링크 된 페이지 가 사라진 것처럼 보이지만 응답 중 하나가 필요할 수 있습니다.

실제로 US_export_policy.jar 및 local_policy.jar를 core / lib / jce에서 $ JAVA_HOME / jre / lib / security로 복사하는 것이 도움이되었습니다. 감사.


감사합니다,하지만 내가 가지고 US_export_policy.jarlocal_policy.jar내 lib 디렉토리 / 보안 폴더에 내가 자바를 설치 한 이미 한번 .. 그리고 내 자바 설치 폴더의 방법으로 코어 / lib 디렉토리 / JCE를 찾을 수 없습니다.
Rihards 2016 년

5

문제는 인 컨텐츠 파일의 default_local.policy 에서 의 local_policy.jar 폴더에 JRE \ lib 디렉토리 \ 보안 당신은 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;
};

전 세계적으로 유효한 설정이 필요하지 않은 경우이 파일을 편집하고 내용을

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

Oracle에서 JCE를 다운로드하면 얻을 수 있습니다.


4

또한 문제가 발생했지만 기존 문제를 다운로드 한 (JCE에서) 대체 한 후에 문제가 해결되었습니다. 새로운 암호화 파일은 무한한 힘을 제공했습니다.


2

기본적으로 Java는 암호화를 위해 AES 128 비트 (16 바이트) 키 크기 만 지원합니다. 기본 지원 이상을 필요로하지 않으면를 사용하기 전에 키를 적절한 크기로자를 수 있습니다 Cipher. 지원되는 기본 키는 javadoc 을 참조하십시오 .

정책 파일을 수정하지 않고 모든 JVM 버전에서 작동하는 키를 생성하는 예입니다. 자신의 재량에 따라 사용하십시오.

다음은 AgileBits 블로그 에서 키 128 ~ 256 키 크기가 중요한지 에 대한 좋은 기사입니다.

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);
}

암호화 각 암호화 유형에 대한 유효한 키 크기에 클래스 문서를 가리 킵니다.
keaplogik

FIPS 197의 NIST에서 지정한 Oracle 문서 암호 (암호화) 알고리즘 AES : 고급 암호화 표준을 참조하십시오 . Joan Daemen과 Vincent Rijmen이 Rijndael 알고리즘이라고도하는 AES는 128, 192의 키를 지원하는 128 비트 블록 암호입니다. 256 비트
zaph

사실 일 수도 있지만, 클래스 설명서에 지정된대로 128 비트를 지원하려면 각 Java 버전에서만 필요합니다. 스스로를 테스트하고 당신은 당신이에서 정책 항아리가 필요합니다 찾을 제임스 블랙의 답변을 다른 키 크기를 할
keaplogik

256 비트 키를 지원하지 않는 AES 구현은 256 비트 키를 사용하여 상당수의 AES 암호화를 해독 할 수 없으므로 본질적으로 쓸모가 없습니다.
zaph

1
256 비트 키가 필요한 경우 가장 좋은 해결책은 아마도 유일한 솔루션 일 수도 있으며 필요한 경우 정책 파일을 설치하고 키를 자르지 않아 잠재적으로 보안을 약화 시키며 상호 운용성의 경우 불가능할 수도 있습니다.
zaph

2

Java 9 또는 8u151부터는 파일에서 주석 행을 사용할 수 있습니다.

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

그리고 변경 :

#crypto.policy=unlimited

crypto.policy=unlimited

2

apt와 함께 Linux 배포를 사용하고 webupd8 PPA를 추가 한 경우 간단히 명령을 실행할 수 있습니다

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

다른 업데이트 :

  1. 무제한 강도 관할 정책 파일은 Java 9에 포함되어 있으며 기본적으로 사용됩니다
  2. 시작 자바 8 업데이트 (161) 무제한 강도 관할 정책, 자바 (8)는 기본값을.
  3. Java 8 업데이트 151 부터는 Unlimited Strength Jurisdiction Policy가 Java 8에 포함되어 있지만 기본적으로 사용되지 않습니다. 사용 가능하게하려면 <java_home>/jre/lib/security(JDK 용) 또는 <java_home>/lib/security(JRE 용 ) 에서 java.security 파일을 편집해야합니다 . 줄을 주석 해제 (또는 포함)

    crypto.policy=unlimited

    관리자 권한으로 편집기 실행을 사용하여 파일을 편집하십시오. 정책 변경은 JVM을 다시 시작한 후에 만 ​​적용됩니다.

전에 자바 8 업데이트 (151) 답변의 나머지 부분은 유효십시오. JCE 무제한 강도 관할 정책 파일을 다운로드하고 교체하십시오.

자세한 내용은 아래의 개인 블로그 게시물 -JCE (Java Cryptography Extension) 무제한 강도 관할 정책 파일 설치 방법을 참조하십시오.


1

이 문제를 해결하기위한 두 가지 옵션이 있습니다

옵션 번호 1 : 길이가 RSA 2048 인 인증서 사용

옵션 번호 2 :jre\lib\security java http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html 을 사용하는 모든 곳 에서 두 개의 항아리를 업데이트합니다 .

또는 IBM websphere 또는 해당 java를 사용하는 모든 애플리케이션 서버를 사용합니다. 내가 직면 한 주요 문제는 websphere에 귀를 배치했을 때 최대 길이의 인증을 사용했는데 동일한 예외가 발생했습니다.

Java Security: Illegal key size or default parameters?

두 개의 항아리로 websphere의 java intsalled 폴더를 업데이트했습니다 https://www14.software.ibm.com/webapp/iwm/web/reg/pick.do?source=jcesdk&lang=en_US

링크 https://www-01.ibm.com/support/docview.wss?uid=swg21663373 에서 참조를 확인할 수 있습니다.


1

최신 버전의 JDK / JRE 를 사용해야 합니다. .

필자의 경우 JCE를 JRE 폴더에 넣었지만 도움이되지 않았습니다. IDE에서 직접 프로젝트를 실행했기 때문에 발생했습니다 (JDK 사용).

그런 다음 JDK와 JRE를 최신 버전 (1.8.0_211)으로 업데이트했는데 문제가 발생했습니다.

자세한 내용은 https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8170157


1

기본 JDK는 미국 제한으로 인해 128 비트 키를 통해서만 암호화를 지원합니다. 그래서 암호화를 지원하는 256 비트 길이의 키에서 우리는 교체해야 local_policy.jar하고 US_export_policy.jars$JAVA_HOME/java-8-oracle/jre/lib/security폴더 그렇지 않으면 줄 것이다 :

java.security.InvalidKeyException : 잘못된 키 크기 또는 기본값


0

거기 가야 해요

/jdk1.8.0_152 | / jre | / lib | / 보안 | java.security 및 주석 해제

#crypto.policy=unlimited

crypto.policy=unlimited
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.