Java Security: Ukuran kunci ilegal atau parameter default?


409

Saya telah mengajukan pertanyaan tentang ini sebelumnya, tetapi itu tidak dijawab dengan benar dan tidak mengarah ke mana pun.

Jadi saya telah mengklarifikasi beberapa detail tentang masalah ini dan saya sangat ingin mendengar ide Anda tentang bagaimana saya bisa memperbaiki ini atau apa yang harus saya coba.

Saya telah menginstal Java 1.6.0.12 di server Linux saya dan kode di bawah ini berjalan dengan sempurna.

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

Hari ini saya menginstal Java 1.6.0.26 pada pengguna server saya dan ketika saya mencoba menjalankan aplikasi saya, saya mendapatkan pengecualian berikut. Dugaan saya ada hubungannya dengan konfigurasi instalasi Java karena ia bekerja di yang pertama, tetapi tidak berfungsi di versi yang lebih baru.

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

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

Catatan:
* java.security pada direktori java 1.6.0.12 server hampir sepenuhnya cocok dengan file java.security 1.6.0.26 . Tidak ada penyedia tambahan di yang pertama.
* Pertanyaan sebelumnya ada di sini .



4
Ini juga dapat dianggap sebagai kesalahan: Caused by: java.security.InvalidKeyException: Illegal key size(tanpa "atau parameter default") di Java 8
hackajar

Cukup gunakan OpenJDK dan itu akan berhasil.
Rodrigo Asensio

@RodrigoAsensio: Saya menggunakan OpenJDK dan tidak berfungsi dengannya. Anda harus menginstal file jar File Kebijakan Yurisdiksi Kekuatan yang tidak terbatas. Dan itu akan berhasil.
anjanb

5
Perbarui untuk jawaban @AniketThakur. Karena Java 9 dan Java 8u151 tidak perlu lagi mengunduh dan menginstal file kebijakan yurisdiksi secara manual. Untuk mengaktifkan kriptografi tanpa batas, seseorang dapat menggunakan properti Keamanan crypto.policy baru. Jika properti Keamanan baru (crypto.policy) diatur dalam file java.security, atau telah ditetapkan secara dinamis dengan menggunakan panggilan Security.setProperty () sebelum kerangka kerja JCE telah diinisialisasi, pengaturan itu akan dihormati. Secara default, properti akan tidak terdefinisi.
Marcin Kłopotek

Jawaban:


722

Kemungkinan besar Anda tidak memiliki file kekuatan tak terbatas yang diinstal sekarang.

Anda mungkin perlu mengunduh file ini:

Java Cryptography Extension (JCE) File Kebijakan Yurisdiksi Kekuatan Tidak Terbatas 6

Java Cryptography Extension (JCE) File Kebijakan Yurisdiksi Kekuatan Tidak Terbatas 7 Unduh

Java Cryptography Extension (JCE) Kebijakan File 8 Yurisdiksi Kekuatan Tidak Terbatas (hanya diperlukan untuk versi sebelum Java 8 u162)

Ekstrak file jar dari zip dan simpan di ${java.home}/jre/lib/security/.


2
@JamesBlack - Yep, dan memastikan semua basis tertutup saya meletakkan di bawah JAR ini Java/jre/lib/security, Java/jdk/lib/security, dan Java/jdk/jre/lib/security. Menjalankan 'java -versi' mengembalikan rincian yang diharapkan.
Agustus

5
Untuk SDK IBM (misalnya, WebSphere), unduh file kebijakan yurisdiksi tidak terbatas dari www14.software.ibm.com/webapp/iwm/web/preLogin.do?source=jcesdk
quietmint

4
Karena Java 9 dan Java 8u151 tidak perlu lagi mengunduh dan menginstal file kebijakan yurisdiksi secara manual. Untuk mengaktifkan kriptografi tanpa batas, seseorang dapat menggunakan properti Keamanan crypto.policy baru. Jika properti Keamanan baru (crypto.policy) diatur dalam file java.security, atau telah ditetapkan secara dinamis dengan menggunakan panggilan Security.setProperty () sebelum kerangka kerja JCE telah diinisialisasi, pengaturan itu akan dihormati. Secara default, properti akan tidak terdefinisi.
Marcin Kłopotek

4
Jadi, jawaban yang dibarui ini sudah ketinggalan zaman, dan sudah usang. Bagaimana cara kami meningkatkan atau menekan jawaban ini sehingga stackoverflow.com/a/46857694/2808798 dapat menjadi jawaban "diterima"?
Jesse Adelman

3
@JesseAdelman - Sayangnya ini hampir 7 tahun, tidak banyak yang bisa dilakukan. Siapa pun yang bertanya perlu mengubahnya.
James Black

54

File-file yurisdiksi JRE / JDK / Java 8 dapat ditemukan di sini:

Java Cryptography Extension (JCE) File Kebijakan Yurisdiksi Kekuatan Tidak Terbatas 8

Seperti yang dikatakan James di atas:
Instal file dalam ${java.home}/jre/lib/security/.


2
Sudah mencoba menggunakan 6 dan 7, tetapi mereka tidak berhasil. Harus menginstal 8. Terima kasih.
Jason Kim

9
Rilis baru JDK 8u151 memiliki "Properti Keamanan Baru untuk mengontrol kebijakan kripto". Sekarang perubahan properti untuk beralih. Intinya: hapus "#" dari baris "# crypto.policy = tidak terbatas" di "lib \ security \ java.security" untuk mengaktifkan menggunakan kunci 256-bit. oracle.com/technetwork/java/javase/8u151-relnotes-3850493.html
hemisphire

1
Terima kasih! Karena ini adalah properti keamanan, Anda juga dapat menghubungi Security.setProperty ("crypto.policy", "unlimited"). Sumber: tautan
@hemisphire

42

Untuk JAVA 7 tautan unduhan adalah jce-7-download

Salin dua guci yang diunduh di Java \ jdk1.7.0_10 \ jre \ lib \ security
Ambil cadangan guci yang lebih lama agar berada di sisi yang lebih aman.

Untuk JAVA 8 tautan unduhannya adalah jce-8-download.
Menyalin guci yang diunduh di Java \ jdk1.8.0_45 \ jre \ lib \ security
Ambil cadangan guci yang lebih tua agar berada di sisi yang lebih aman.


39

Dengan Java 9, Java 8u161 , Java 7u171 dan Java 6u181 batasan sekarang dinonaktifkan secara default. Lihat masalah di Java Bug Database .


Dimulai dengan Java 8u151 Anda dapat menonaktifkan batasan secara terprogram.

Dalam rilis yang lebih lama, file yurisdiksi JCE harus diunduh dan diinstal secara terpisah untuk memungkinkan kriptografi yang tidak terbatas untuk digunakan oleh JDK. Langkah-langkah unduh dan instal tidak lagi diperlukan.

Alih-alih, Anda sekarang dapat menjalankan baris berikut sebelum pertama kali menggunakan kelas JCE (yaitu lebih baik setelah aplikasi dimulai):

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

Bagaimana dengan di Android? Di tingkat API manakah metode pembatasan ini dapat diselesaikan?
TheRealChx101

31

Ini adalah solusi hanya kode . Tidak perlu mengunduh atau mengacaukan file konfigurasi.

Ini adalah solusi berbasis refleksi, diuji di java 8

Panggil metode ini satu kali, di awal program Anda.

// Impor

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

//metode

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
}

Kredit: Delthas


4
Harap dicatat bahwa ini dapat melanggar perjanjian lisensi Java SE: D. BATASAN PEMBATASAN TEKNOLOGI. Anda tidak boleh membuat, memodifikasi, atau mengubah perilaku, atau mengizinkan pemegang lisensi untuk membuat, memodifikasi, atau mengubah perilaku, kelas, antarmuka, atau sub paket yang dengan cara apa pun diidentifikasi sebagai "java", "javax", " javafx "," sun "," oracle "atau konvensi serupa seperti yang ditentukan oleh Oracle dalam setiap penamaan konvensi penamaan. [...] sumber
SimMac

Terima kasih banyak


16

Saya mengalami kesalahan yang sama saat menggunakan Windows 7 x64, Eclipse, dan JDK 1.6.0_30. Di folder instalasi JDK ada jrefolder. Ini membuat saya kecewa pada awalnya karena saya menambahkan guci tersebut ke folder lib / keamanan JDK tanpa hasil. Jalur penuh:

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

Unduh dan ekstrak file yang ada di jcefolder arsip ini ke folder itu.


16

Di Jawa, secara default AES mendukung kunci 128 Bit, jika Anda berencana untuk menggunakan kunci 192 Bit atau 256 Bit, pengolah java akan membuang Pengecualian ukuran kunci ilegal, yang Anda dapatkan.

Solusinya adalah seperti yang disarankan victor & James, Anda harus mengunduh JCE (Java Cryptography Extension) sesuai versi JRE Anda, (java6, java7 atau java8).

Zip JCE berisi JAR berikut:

  1. local_policy.jar
  2. US_export_policy.jar

Anda perlu mengganti toples ini dari bentuk Anda <JAVA_HOME>/jre/lib/security. jika Anda menggunakan sistem unix, mungkin akan merujuk/home/urs/usr/lib/jvm/java-<version>-oracle/

Kadang-kadang hanya mengganti local_policy.jar, US_export_policy.jar di folder keamanan tidak berfungsi di unix, jadi saya sarankan untuk menyalin folder keamanan ke desktop Anda terlebih dahulu, ganti folder @ Desktop / keamanan jar, hapus folder keamanan dari / jre / lib / & Pindahkan folder keamanan Desktop ke / jre / lib /.

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


5

Ada diskusi singkat tentang apa yang tampaknya menjadi masalah ini di sini . Halaman yang ditautkan tampaknya hilang, tetapi salah satu respons mungkin yang Anda butuhkan:

Memang, menyalin US_export_policy.jar dan local_policy.jar dari inti / lib / jce ke $ JAVA_HOME / jre / lib / keamanan membantu. Terima kasih.


Terima kasih, tapi saya sudah US_export_policy.jardan local_policy.jardi folder lib / security saya sudah begitu saya menginstal Java .. Dan saya tidak bisa menemukan core / lib / jce dengan cara di folder instalasi Java saya.
Rihards

5

masalahnya adalah isi dari file default_local.policy di local_policy.jar di folder jre \ lib \ security , jika Anda menginstal 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;
};

jika Anda tidak memerlukan pengaturan yang berlaku di seluruh dunia, Anda cukup dapat mengedit file ini dan mengubah konten

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

inilah yang didapat jika Anda mengunduh JCE dari Oracle.


4

Saya juga mendapatkan masalah tetapi setelah mengganti yang sudah ada dengan yang diunduh (dari JCE) satu menyelesaikan masalah. File crypto baru memberikan kekuatan tak terbatas.


2

Secara default, Java hanya mendukung ukuran kunci AES 128 bit (16 byte) untuk enkripsi. Jika Anda tidak membutuhkan lebih dari yang didukung standar, Anda dapat memotong kunci ke ukuran yang tepat sebelum menggunakan Cipher. Lihat javadoc untuk kunci yang didukung standar.

Ini adalah contoh menghasilkan kunci yang akan berfungsi dengan versi JVM apa pun tanpa memodifikasi file kebijakan. Gunakan dengan kebijaksanaan Anda sendiri.

Berikut ini adalah artikel yang bagus tentang apakah kunci 128 hingga 256 ukuran kunci penting di AgileBits Blog

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

The Cipher kelas dokumentasi poin untuk ukuran kunci yang valid untuk setiap jenis kripto.
keaplogik

Lihat dokumen Oracle Cipher (Enkripsi) Algoritma AES: Advanced Encryption Standard seperti yang ditentukan oleh NIST dalam FIPS 197. Juga dikenal sebagai algoritma Rijndael oleh Joan Daemen dan Vincent Rijmen, AES adalah cipher blok 128-bit yang mendukung kunci 128, 192, dan 256 bit.
zaf

Itu mungkin benar, tetapi hanya diperlukan oleh setiap versi Java untuk mendukung 128-bit seperti yang ditentukan dalam dokumentasi kelas. Uji sendiri dan Anda akan menemukan Anda memerlukan toples kebijakan dari jawaban James Black untuk melakukan ukuran kunci lainnya
keaplogik

Setiap implementasi AES yang tidak mendukung kunci 256-bit pada dasarnya tidak akan berguna karena tidak akan dapat mendekripsi sejumlah besar enkripsi AES menggunakan kunci 256-bit.
zaf

1
Jika kunci 256-bit diperlukan solusi terbaik, mungkin satu-satunya solusi, adalah menginstal file Kebijakan jika diperlukan, tidak memotong kunci yang berpotensi melemahkan keamanan dan mungkin tidak mungkin dalam kasus interoperabilitas.
zaf

2

Mulai dari Java 9 atau 8u151, Anda dapat menggunakan komentar pada baris di file:

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

Dan ubah:

#crypto.policy=unlimited

untuk

crypto.policy=unlimited

2

Jika Anda menggunakan distribusi Linux dengan apt dan telah menambahkan PPA webupd8, Anda cukup menjalankan perintah

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

Pembaruan lainnya:

  1. File Kebijakan Yurisdiksi Kekuatan Tidak Terbatas disertakan dengan Java 9 dan digunakan secara default
  2. Dimulai dengan Java 8 Pembaruan 161 , Java 8 default ke Kebijakan Yurisdiksi Kekuatan Tidak Terbatas.
  3. Dimulai dengan Java 8 Pembaruan 151 , Kebijakan Yurisdiksi Kekuatan Tidak Terbatas disertakan dengan Java 8 tetapi tidak digunakan secara default. Untuk mengaktifkannya, Anda perlu mengedit file java.security di <java_home>/jre/lib/security(untuk JDK) atau <java_home>/lib/security(untuk JRE). Batalkan komentar (atau sertakan) garis

    crypto.policy=unlimited

    Pastikan Anda mengedit file menggunakan editor yang dijalankan sebagai administrator. Perubahan kebijakan hanya berlaku setelah memulai ulang JVM

Sebelum Java 8 Perbarui 151 sisa jawaban berlaku. Unduh File Kebijakan Yurisdiksi Kekuatan Tidak Terbatas JCE dan gantikan.

Untuk detail lebih lanjut, Anda dapat merujuk ke posting blog pribadi saya di bawah ini - Cara menginstal Java Cryptography Extension (JCE) file kebijakan yurisdiksi kekuatan tidak terbatas yang kuat


1

ada dua opsi untuk mengatasi masalah ini

opsi nomor 1: gunakan sertifikat dengan panjang kurang dari RSA 2048

opsi nomor 2: Anda akan memperbarui dua botol di jre\lib\security apa pun yang Anda gunakan java http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html

atau Anda menggunakan IBM websphere atau server aplikasi apa pun yang menggunakan java-nya. masalah utama yang saya hadapi saya menggunakan sertifikasi dengan panjang maksimal, ketika saya memasang telinga di websphere pengecualian yang sama dilemparkan

Java Security: Illegal key size or default parameters?

saya memperbarui folder java intsalled di websphere dengan dua stoples https://www14.software.ibm.com/webapp/iwm/web/reg/pick.do?source=jcesdk&lang=en_US

Anda dapat memeriksa referensi di tautan https://www-01.ibm.com/support/docview.wss?uid=swg21663373


1

Pastikan Anda menggunakan JDK / JRE versi terbaru .

Dalam kasus saya, saya telah memasukkan JCE ke folder JRE, tetapi tidak membantu. Itu terjadi karena saya menjalankan proyek saya dari IDE secara langsung (menggunakan JDK).

Kemudian saya memperbarui JDK dan JRE saya ke versi terbaru (1.8.0_211) dan masalahnya telah hilang.

Detail lebih lanjut: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8170157


1

JDK default mendukung enkripsi hanya melalui kunci 128 bit karena pembatasan Amerika. Jadi untuk mendukung enkripsi dari kunci panjang 256 bit kita harus mengganti local_policy.jardan US_export_policy.jarsdalam $JAVA_HOME/java-8-oracle/jre/lib/securityfolder kalau tidak akan memberikan:

java.security.InvalidKeyException: ukuran kunci ilegal atau default


0

Anda harus pergi ke sana

/jdk1.8.0_152 | / jre | / lib | / keamanan | keamanan java dan batalkan komentar pada

#crypto.policy=unlimited

untuk

crypto.policy=unlimited
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.