জাভা কি চলুন এনক্রিপ্ট শংসাপত্রগুলি সমর্থন করে?


125

আমি একটি জাভা অ্যাপ্লিকেশন বিকাশ করছি যা HTTP- র মাধ্যমে রিমোট সার্ভারে একটি REST এপিআইয়ের অনুসন্ধান করে। সুরক্ষার কারণে এই যোগাযোগটি এইচটিটিপিএসে পরিবর্তন করা উচিত।

এখন আসুন যে এনক্রিপ্টটি তাদের সর্বজনীন বিটা শুরু করেছিল, আমি জানতে চাই যে জাভা বর্তমানে তাদের শংসাপত্রগুলি ডিফল্টরূপে কাজ করে (বা ভবিষ্যতে কাজ করার বিষয়ে নিশ্চিত হয়েছে)।

আসুন এনক্রিপ্ট তাদের ইডেনট্রাস্টের মধ্যবর্তী ক্রস-স্বাক্ষরিত হ'ল , এটি ভাল সংবাদ should তবে, এই আদেশের আউটপুটে আমি এই দুটিয়ের কোনওটিই খুঁজে পাচ্ছি না:

keytool -keystore "..\lib\security\cacerts" -storepass changeit -list

আমি জানি যে বিশ্বস্ত সিএগুলি প্রতিটি মেশিনে ম্যানুয়ালি যুক্ত করা যেতে পারে, তবে যেহেতু আমার অ্যাপ্লিকেশনটি ডাউনলোডের জন্য নিখরচায় এবং কোনও কনফিগারেশন ছাড়াই এক্সিকিউটেবল হওয়া উচিত, তাই আমি এমন সমাধানগুলির সন্ধান করছি যা "বাক্সের বাইরে" কাজ করে। আপনার কি আমার জন্য সুসংবাদ আছে?



@ স্পটাম "জাভা 8u131 এর সাথে আপনাকে এখনও আপনার ট্রস্টস্টোরে আপনার শংসাপত্রটি যুক্ত করতে হবে" সুতরাং আপনি যদি লেটস এনক্রিপ্টের থেকে কোনও শংসাপত্র পান, আপনি ট্রাস্টস্টোরটিতে যে শংসাপত্রটি পেয়েছেন তা যুক্ত করতে হবে? তাদের সিএ অন্তর্ভুক্ত করা কি যথেষ্ট হবে না?
এমএক্স্রো

1
@ এমএক্স্রো হাই - এতে আমার দৃষ্টি আকর্ষণ করার জন্য ধন্যবাদ। উপরের আমার মন্তব্যগুলি মোটেই সত্য হয় না (আসলে সমস্যাটি এর চেয়ে জটিলতর ছিল এবং আমাদের অবকাঠামোর সাথে সম্পর্কিত) এবং আমি সেগুলি সরাতে যাচ্ছি কারণ তারা প্রকৃতপক্ষে কেবল বিভ্রান্তির দিকে পরিচালিত করছে। সুতরাং আপনার যদি jdk> জাভা 8u101 থাকে, আসুন এনক্রিপ্ট শংসাপত্রটি কাজ করা উচিত এবং সঠিকভাবে স্বীকৃত এবং বিশ্বাসযোগ্য হওয়া উচিত।
পটামাম

@ পোটেম এটি দুর্দান্ত। সুস্পষ্ট করার জন্য ধন্যবাদ!
এমএক্সরো

উত্তর:


142

[ আপডেট ২০১-0-০6-০৮ : https://bugs.openjdk.java.net/browse/JDK-8154757 অনুসারে ইডেন ট্রাস্ট সিএ ওরাকল জাভা 8u101 এ অন্তর্ভুক্ত করা হবে।]

[ আপডেট 2016-08-05: জাভা 8u101 প্রকাশিত হয়েছে এবং সত্যই ইডেনট্রাস্ট সিএ অন্তর্ভুক্ত করেছে: রিলিজ নোট ]


জাভা কি চলুন এনক্রিপ্ট শংসাপত্রগুলি সমর্থন করে?

হ্যাঁ. লেটস এনক্রিপ্ট শংসাপত্রটি কেবল একটি নিয়মিত পাবলিক কী শংসাপত্র। জাভা এটি সমর্থন করে ( জাভা 7> = 7u111 এবং জাভা 8> = 8u101 এর জন্য চলুন এনক্রিপ্ট শংসাপত্রের সামঞ্জস্যতা অনুসারে) supports

জাভা কি বিশ্বাস করি চলুন বাক্সের বাইরে থাকা এনক্রিপ্ট শংসাপত্রগুলি?

না / এটি জেভিএমের উপর নির্ভর করে। 8u66 অবধি ওরাকল জেডিকে / জেআরই এর ট্রাস্টস্টোরটিতে বিশেষত লেটস এনক্রিপ্ট সিএ বা আইডেন ট্রাস্ট সিএ নেই যা এতে স্বাক্ষর করেছে। new URL("https://letsencrypt.org/").openConnection().connect();উদাহরণস্বরূপ ফলাফলjavax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException

তবে আপনি আপনার নিজস্ব বৈকল্পিক সরবরাহ করতে পারেন / একটি কাস্টম কীস্টোর সংজ্ঞায়িত করতে পারেন যা প্রয়োজনীয় মূল সিএ রয়েছে বা জেভিএম ট্রাস্টস্টোরে শংসাপত্রটি আমদানি করতে পারে।

https://commune.letsencrypt.org/t/will-the-cross-root-cover-trust-by-the-default-list-in-td-jdk-jre/134/10 এ বিষয়টিও আলোচনা করে।


এখানে কয়েকটি উদাহরণ কোড রয়েছে যা রানটাইমে ডিফল্ট ট্রাস্টস্টোরের শংসাপত্র যুক্ত করতে পারে তা দেখায়। আপনাকে কেবল শংসাপত্রটি যুক্ত করতে হবে (ফায়ারফক্স থেকে .der হিসাবে রফতানি করে ক্লাসপথে লাগানো)

জাভাতে আমি কীভাবে বিশ্বস্ত রুট শংসাপত্রগুলির একটি তালিকা পেতে পারি তার উপর নির্ভর করে ? এবং http://developer.android.com/training/articles/security-ssl.html#UnعلومCa

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.PKIXParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.TrustManagerFactory;

public class SSLExample {
    // BEGIN ------- ADDME
    static {
        try {
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            Path ksPath = Paths.get(System.getProperty("java.home"),
                    "lib", "security", "cacerts");
            keyStore.load(Files.newInputStream(ksPath),
                    "changeit".toCharArray());

            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            try (InputStream caInput = new BufferedInputStream(
                    // this files is shipped with the application
                    SSLExample.class.getResourceAsStream("DSTRootCAX3.der"))) {
                Certificate crt = cf.generateCertificate(caInput);
                System.out.println("Added Cert for " + ((X509Certificate) crt)
                        .getSubjectDN());

                keyStore.setCertificateEntry("DSTRootCAX3", crt);
            }

            if (false) { // enable to see
                System.out.println("Truststore now trusting: ");
                PKIXParameters params = new PKIXParameters(keyStore);
                params.getTrustAnchors().stream()
                        .map(TrustAnchor::getTrustedCert)
                        .map(X509Certificate::getSubjectDN)
                        .forEach(System.out::println);
                System.out.println();
            }

            TrustManagerFactory tmf = TrustManagerFactory
                    .getInstance(TrustManagerFactory.getDefaultAlgorithm());
            tmf.init(keyStore);
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, tmf.getTrustManagers(), null);
            SSLContext.setDefault(sslContext);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    // END ---------- ADDME

    public static void main(String[] args) throws IOException {
        // signed by default trusted CAs.
        testUrl(new URL("https://google.com"));
        testUrl(new URL("https://www.thawte.com"));

        // signed by letsencrypt
        testUrl(new URL("https://helloworld.letsencrypt.org"));
        // signed by LE's cross-sign CA
        testUrl(new URL("https://letsencrypt.org"));
        // expired
        testUrl(new URL("https://tv.eurosport.com/"));
        // self-signed
        testUrl(new URL("https://www.pcwebshop.co.uk/"));

    }

    static void testUrl(URL url) throws IOException {
        URLConnection connection = url.openConnection();
        try {
            connection.connect();
            System.out.println("Headers of " + url + " => "
                    + connection.getHeaderFields());
        } catch (SSLHandshakeException e) {
            System.out.println("Untrusted: " + url);
        }
    }

}

আরও একটি জিনিস: আমার কোন ফাইলটি ব্যবহার করা উচিত? আসুন এনক্রিপ্ট ডাউনলোডের জন্য একটি মূল এবং চারটি অন্তর্বর্তী শংসাপত্র সরবরাহ করে । আমি চেষ্টা isrgrootx1.derএবং lets-encrypt-x1-cross-signed.der, কিন্তু তাদের কেউই সঠিক বলে মনে হয়।
হেক্সাহোলিক

@ হেক্সাহোলিক আপনি কী বিশ্বাস করতে চান এবং কীভাবে আপনি ব্যবহার করা সাইটটিতে শংসাপত্র রয়েছে তা নির্ভর করে has https://helloworld.letsencrypt.orgউদাহরণস্বরূপ যান এবং ব্রাউজারে শংসাপত্র শৃঙ্খলা পরিদর্শন করুন (সবুজ আইকন ক্লিক করুন)। এটির জন্য আপনার অবশ্যই সাইটের নির্দিষ্ট শংসাপত্র, এক্স 1 অন্তর্বর্তী একটি (আইডেনট্রাস্ট দ্বারা স্বাক্ষরিত ক্রস) বা ডিআরএসআরএসটিএএএক্সএক্স 3 একটি দরকার। ISRG Root X1কারণ এটি শৃঙ্খল বিকল্প শৃঙ্খল যে নাই helloworld সাইটের জন্য কাজ করে না। আমি ডিআরএসআরট একটি ব্যবহার করব, কেবল ব্রাউজারের মাধ্যমে রফতানি করলাম কারণ আমি এটি কোথাও ডাউনলোডের জন্য দেখিনি।
zapl

1
কোডের জন্য আপনাকে ধন্যবাদ। কীস্টোর.লোড (ফাইলসনিউইনপুটস্ট্রিম (কেএসপথ)) এ ইনপুট স্ট্রিমটি বন্ধ করতে ভুলবেন না।
মাইকেল ওয়াইরাজ

3
@ adapt-dev না, সফ্টওয়্যার কেন ভাল শংসাপত্র সরবরাহ করতে অজানা সিস্টেমে বিশ্বাস করবে? সফ্টওয়্যারটির শংসাপত্রগুলি এটি নির্ভর করে যা এটি বিশ্বাস করে trust এটির জন্য যদি আমার জাভা প্রোগ্রামটি কোনও এলিস প্রোগ্রামের জন্য শংসাপত্র ইনস্টল করতে পারে তবে এটি একটি সুরক্ষা গর্ত হবে। তবে এটি এখানে ঘটে না, কোডটি কেবল নিজের রানটাইম
zapl

3
কোডটি দেখানোর জন্য +1 যা কেবলমাত্র javax.net.ssl.trustStoreসিস্টেমের সম্পত্তি সেট করে প্রতারণা করে না , তবে JVM এর ডিফল্ট সেট করার জন্য -1 SSLContext। একটি নতুন তৈরি করা ভাল SSLSocketFactoryএবং তারপরে HttpUrlConnectionএটি ভিএম-ওয়াইড এসএসএল কনফিগারেশনের পরিবর্তে বিভিন্ন সংযোগের জন্য (যেমন ) ব্যবহার করা ভাল । (আমি বুঝতে পারি যে এই পরিবর্তনটি কেবল চলমান জেভিএমের জন্য কার্যকর এবং এটি অন্য প্রোগ্রামগুলিকে অবিচ্ছিন্ন বা প্রভাবিত করে না just আমি কেবলমাত্র আপনার কনফিগারেশনটি প্রযোজ্য সে সম্পর্কে স্পষ্ট হওয়া আরও ভাল প্রোগ্রামিং অনুশীলন বলে মনে করি))
ক্রিস্টোফার শুল্টজ

65

আমি জানি ওপি স্থানীয় কনফিগারেশন পরিবর্তন ছাড়াই সমাধান চেয়েছিল, তবে আপনি যদি স্থায়ীভাবে কীস্টোরে ট্রাস্ট চেইন যুক্ত করতে চান:

$ keytool -trustcacerts \
    -keystore $JAVA_HOME/jre/lib/security/cacerts \
    -storepass changeit \
    -noprompt \
    -importcert \
    -file /etc/letsencrypt/live/hostname.com/chain.pem

উৎস: https://commune.letsencrypt.org/t/will-the-cross-root-cover-trust-by-the-default-list-in-the-jdk-jre/134/13


6
হ্যাঁ, ওপি এটি চেয়েছিল না, তবে এটি ছিল আমার পক্ষে সহজতম সমাধান!
অ্যাসপেক্স

আমি আমার পুরানো জাভা 8 বিল্ডে এই সার্টটি লেটসেনক্রিপ.আর.আরএসটিস / স্কটস / এনক্রিপট- এক্স3- ক্রস-sign.pem.txt আমদানি করেছি এবং যে ওয়েব পরিষেবাটি এনক্রিপ্ট শংসাপত্র ব্যবহার করছে তা পৌঁছনীয় নয়! এই সমাধানটি দ্রুত এবং সহজ ছিল।
ইজওয়াইটার

56

আমাদের মধ্যে যারা স্থানীয় কনফিগারেশন পরিবর্তন করতে ইচ্ছুক তাদের জন্য বিশদ উত্তর যা কনফিগার ফাইলটির ব্যাক আপ অন্তর্ভুক্ত রয়েছে:

1. পরিবর্তনগুলির আগে এটি কাজ করছে কিনা পরীক্ষা করুন

আপনার যদি ইতিমধ্যে কোনও পরীক্ষার প্রোগ্রাম না থাকে তবে আপনি আমার জাভা এসএসএলপিং পিং প্রোগ্রাম ব্যবহার করতে পারেন যা টিএলএস হ্যান্ডশেক পরীক্ষা করে (কোনও এইচএসটি / টিএলএস পোর্ট দিয়ে কাজ করবে, কেবল এইচটিটিপিএস নয়)। আমি প্রি-বিল্ট এসএসএলপিং.জার ব্যবহার করব, তবে কোডটি পড়া এবং নিজে এটি তৈরি করা একটি দ্রুত এবং সহজ কাজ:

$ git clone https://github.com/dimalinux/SSLPing.git
Cloning into 'SSLPing'...
[... output snipped ...]

যেহেতু আমার জাভা সংস্করণটি 1.8.0_101 এরও আগের (এই লেখার সময় প্রকাশিত হয়নি), আসুন একটি এনক্রিপ্ট শংসাপত্র ডিফল্টভাবে যাচাই করবে না। সমাধানটি প্রয়োগের আগে ব্যর্থতা দেখতে কেমন তা দেখি:

$ java -jar SSLPing/dist/SSLPing.jar helloworld.letsencrypt.org 443
About to connect to 'helloworld.letsencrypt.org' on port 443
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
[... output snipped ...]

২. শংসাপত্রটি আমদানি করুন

আমি জ্যাভাআহোম এনভায়রনমেন্ট ভেরিয়েবল সেট সহ ম্যাক ওএস এক্সে আছি। পরবর্তী কমান্ডগুলি ধরে নেবে যে এই পরিবর্তনশীলটি আপনি পরিবর্তন করছেন এমন জাভা ইনস্টলেশনটির জন্য সেট করা আছে:

$ echo $JAVA_HOME 
/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/

ক্যাসেটারস ফাইলটির একটি ব্যাকআপ নিন আমরা সংশোধন করব যাতে আপনি জেডিকে পুনরায় ইনস্টল না করে যে কোনও পরিবর্তন ব্যাকআপ করতে পারেন:

$ sudo cp -a $JAVA_HOME/jre/lib/security/cacerts $JAVA_HOME/jre/lib/security/cacerts.orig

আমাদের আমদানি করতে হবে এমন স্বাক্ষর শংসাপত্রটি ডাউনলোড করুন:

$ wget https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.der

আমদানি সম্পাদন করুন:

$ sudo keytool -trustcacerts -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -noprompt -importcert -alias lets-encrypt-x3-cross-signed -file lets-encrypt-x3-cross-signed.der 
Certificate was added to keystore

3. এটি পরিবর্তনগুলির পরে কাজ করছে কিনা তা যাচাই করুন

যাভা এখন এসএসএল পোর্টের সাথে সংযুক্ত হয়ে খুশি তা যাচাই করুন:

$ java -jar SSLPing/dist/SSLPing.jar helloworld.letsencrypt.org 443
About to connect to 'helloworld.letsencrypt.org' on port 443
Successfully connected

8

JDK জন্য যা এখনো আসুন এনক্রিপ্ট সার্টিফিকেট সমর্থন করে না, আপনি JDK সেই যোগ করতে পারেন cacertsএই প্রক্রিয়া (ধন্যবাদ নিম্নলিখিত এই )।

সমস্ত শংসাপত্র https://letsencrypt.org/cerર્ટ ates/ এ ডাউনলোড করুন ( ডার ফর্ম্যাটটি চয়ন করুন ) এবং এ জাতীয় আদেশের সাথে একে একে তাদের যুক্ত করুন (উদাহরণস্বরূপ letsencryptauthorityx1.der):

keytool -import -keystore PATH_TO_JDK\jre\lib\security\cacerts -storepass changeit -noprompt -trustcacerts -alias letsencryptauthorityx1 -file PATH_TO_DOWNLOADS\letsencryptauthorityx1.der

এটি পরিস্থিতি উন্নতি করে তবে আমি সংযোগ ত্রুটি পেয়েছি: javax.net.ssl.SSLException: java.lang.RuntimeException: DH
keypair
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.