জাভা HTTPS ক্লায়েন্ট শংসাপত্র প্রমাণীকরণ


222

আমি মোটামুটি নতুন HTTPS/SSL/TLSএবং শংসাপত্রগুলির সাথে প্রমাণীকরণের সময় ক্লায়েন্টরা ঠিক কী উপস্থাপন করবে তা নিয়ে আমি কিছুটা বিভ্রান্ত।

আমি একটি জাভা ক্লায়েন্ট লিখছি যা POSTকোনও নির্দিষ্ট ব্যক্তির জন্য সাধারণ ডেটা করা দরকার URL। এই অংশটি ঠিকঠাক কাজ করে, একমাত্র সমস্যাটি এটি শেষ হওয়ার কথা HTTPSHTTPSঅংশ হ্যান্ডেল করা মোটামুটি সহজ (হয় সঙ্গে HTTPclientবা ব্যবহার জাভা এর বিল্ট-ইন HTTPSসমর্থন), কিন্তু আমি ক্লায়েন্ট শংসাপত্রগুলি প্রমাণীকরণ করতে আটকে করছি। আমি লক্ষ্য করেছি যে এখানে ইতিমধ্যে একটি খুব অনুরূপ প্রশ্ন রয়েছে, যা আমি এখনও আমার কোড দিয়ে চেষ্টা করি নি (তাড়াতাড়ি যথেষ্ট হবে)। আমার বর্তমান সমস্যাটি হ'ল - আমি যাই করি না কেন - জাভা ক্লায়েন্ট কখনই শংসাপত্র বরাবর প্রেরণ করে না (আমি এটি PCAPডাম্পগুলি দিয়ে পরীক্ষা করতে পারি )।

আমি জানতে চাই যে শংসাপত্রগুলির সাথে প্রমাণীকরণের সময় ক্লায়েন্টটি ঠিক কী সার্ভারে উপস্থাপন করার কথা ছিল (বিশেষত জাভার জন্য - যদি তা মোটেই গুরুত্বপূর্ণ)? এটি কি একটি JKSফাইল, বা PKCS#12? তাদের মধ্যে যা থাকার কথা; শুধু ক্লায়েন্ট শংসাপত্র, বা একটি চাবি? যদি তাই হয়, কোন চাবি? বিভিন্ন ধরণের ফাইল, শংসাপত্রের ধরণ এবং এ জাতীয় সম্পর্কে বেশ কিছু বিভ্রান্তি রয়েছে।

আমি নতুন হওয়ার আগে বলেছি HTTPS/SSL/TLSতাই আমি কিছু পটভূমি তথ্যেরও প্রশংসা করব (কোনও প্রবন্ধ হতে হবে না; আমি ভাল নিবন্ধগুলির লিঙ্কগুলি স্থির করব)।


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

উত্তর:


233

অবশেষে সমস্ত সমস্যা সমাধান করতে পরিচালিত, তাই আমি আমার নিজের প্রশ্নের উত্তর দেব। এই আমার সেটিংস / ফাইলগুলি যা আমার বিশেষ সমস্যা (গুলি) সমাধান করার জন্য আমি ব্যবহার করেছি;

ক্লায়েন্টের কীস্টোর একটি হল PKCS # 12 এর বিন্যাস ফাইল

  1. ক্লায়েন্টের সর্বজনীন শংসাপত্র (স্ব-স্বাক্ষরিত সিএ স্বাক্ষরিত এই উদাহরণে)
  2. ক্লায়েন্টের ব্যক্তিগত কী

এটি উত্পন্ন করার জন্য আমি ওপেনএসএসএল-এর pkcs12কমান্ড ব্যবহার করেছি , উদাহরণস্বরূপ;

openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12 -name "Whatever"

টিপ: নিশ্চিত করুন যে আপনি সর্বশেষ ওপেনএসএসএল পেয়েছেন, সংস্করণ 0.9.8 ঘন্টা নয় , কারণ এটি এমন কোনও বাগ দ্বারা ভুগছে যা আপনাকে পিকেসিএস # 12 ফাইলগুলি সঠিকভাবে তৈরি করতে দেয় না allow

এই পিকেসিএস # 12 ফাইলটি সার্ভারের কাছে ক্লায়েন্ট শংসাপত্র উপস্থাপন করার জন্য জাভা ক্লায়েন্ট ব্যবহার করবে যখন সার্ভারটি ক্লায়েন্টকে স্পষ্ট করে প্রমাণীকরণের জন্য অনুরোধ করেছিল। ক্লায়েন্ট শংসাপত্র প্রমাণীকরণের প্রোটোকলটি কীভাবে কাজ করে (আমাদের এখানে ক্লায়েন্টের ব্যক্তিগত কী কী প্রয়োজন তাও ব্যাখ্যা করে) এর একটি সংক্ষিপ্তসার জন্য টিপিএসে উইকিপিডিয়া নিবন্ধটি দেখুন ।

ক্লায়েন্টের truststore সোজা এগিয়ে JKS বিন্যাস ফাইল রুট বা মধ্যবর্তী CA সার্টিফিকেট । এই সিএ শংসাপত্রগুলি আপনাকে নির্ধারণ করবে যে আপনাকে কোন শেষ পয়েন্টের সাথে যোগাযোগের অনুমতি দেওয়া হবে, এক্ষেত্রে এটি আপনার ক্লায়েন্টকে যে কোনও সার্ভারের সাথে কোনও শংসাপত্র উপস্থাপন করবে যা ট্রাষ্টস্টোরের সিএর একটিতে স্বাক্ষরিত হয়েছিল certificate

এটি উত্পন্ন করতে আপনি আদর্শ জাভা কীটোল ব্যবহার করতে পারেন, উদাহরণস্বরূপ;

keytool -genkey -dname "cn=CLIENT" -alias truststorekey -keyalg RSA -keystore ./client-truststore.jks -keypass whatever -storepass whatever
keytool -import -keystore ./client-truststore.jks -file myca.crt -alias myca

এই ট্রাস্টস্টোরটি ব্যবহার করে, আপনার ক্লায়েন্ট সিএ দ্বারা স্বাক্ষরিত একটি শংসাপত্র উপস্থাপনকারী সমস্ত সার্ভারের সাথে একটি সম্পূর্ণ এসএসএল হ্যান্ডশেক করার চেষ্টা করবে myca.crt

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

সংস্করণ / মন্তব্য / টিপস

  1. ক্লায়েন্ট শংসাপত্র প্রমাণীকরণ কেবল সার্ভার দ্বারা প্রয়োগ করা যেতে পারে।
  2. ( গুরুত্বপূর্ণ! ) সার্ভার যখন ক্লায়েন্ট শংসাপত্রের (টিএলএস হ্যান্ডশেকের অংশ হিসাবে) অনুরোধ করে তখন এটি শংসাপত্রের অনুরোধের অংশ হিসাবে বিশ্বস্ত সিএর একটি তালিকাও সরবরাহ করে। প্রমাণীকরণের জন্য আপনি যে ক্লায়েন্ট শংসাপত্র উপস্থাপন করতে চান তা হ'ল এই সিএর একটিতে স্বাক্ষরিত নয় , তখন এটি মোটেও উপস্থাপিত হবে না (আমার মতে, এটি একটি অদ্ভুত আচরণ, তবে আমি নিশ্চিত যে এর কোনও কারণ আছে)। এটি আমার সমস্যার মূল কারণ ছিল, কারণ আমার স্ব-স্বাক্ষরিত ক্লায়েন্ট শংসাপত্রটি গ্রহণ করার জন্য অন্য পক্ষটি তাদের সার্ভারটি সঠিকভাবে কনফিগার করেনি এবং আমরা ধরে নিয়েছিলাম যে অনুরোধে ক্লায়েন্ট শংসাপত্রটি সঠিকভাবে সরবরাহ না করার কারণে সমস্যাটি আমার শেষ পর্যায়ে রয়েছে।
  3. ওয়্যারশার্ক পান। এটিতে দুর্দান্ত এসএসএল / এইচটিটিপিএস প্যাকেট বিশ্লেষণ রয়েছে এবং এটি ডিবাগিং এবং সমস্যাটি খুঁজে পেতে একটি দুর্দান্ত সহায়তা করবে। এটি অনুরূপ-Djavax.net.debug=ssl জাভা এসএসএল ডিবাগ আউটপুট নিয়ে অস্বস্তিকর না হলে তবে এটি আরও কাঠামোগত এবং (তর্কযোগ্যভাবে) ব্যাখ্যা করা সহজ।
  4. অ্যাপাচি httpclient লাইব্রেরি ব্যবহার করা পুরোপুরি সম্ভব। আপনি যদি httpclient ব্যবহার করতে চান তবে গন্তব্য URL টি এইচটিটিপিএস সমতুল্য দিয়ে প্রতিস্থাপন করুন এবং নিম্নলিখিত জেভিএম যুক্তি যুক্ত করুন (যে কোনও লাইব্রেরি আপনি এইচটিটিপি / এইচটিটিপিএসের মাধ্যমে ডেটা প্রেরণ / গ্রহণ করতে চান তা নির্বিশেষে) :

    -Djavax.net.debug=ssl
    -Djavax.net.ssl.keyStoreType=pkcs12
    -Djavax.net.ssl.keyStore=client.p12
    -Djavax.net.ssl.keyStorePassword=whatever
    -Djavax.net.ssl.trustStoreType=jks
    -Djavax.net.ssl.trustStore=client-truststore.jks
    -Djavax.net.ssl.trustStorePassword=whatever

6
"প্রমাণীকরণের জন্য আপনি যে ক্লায়েন্ট শংসাপত্রটি উপস্থাপন করতে চান তা যখন এই সিএর একটিতে স্বাক্ষরিত না হয়, তা একেবারেই উপস্থাপিত হবে না"। শংসাপত্রগুলি উপস্থাপন করা হয়নি কারণ ক্লায়েন্ট জানে যে তারা সার্ভার দ্বারা গৃহীত হবে না। এছাড়াও, আপনার শংসাপত্রটি একটি মধ্যবর্তী সিএ "আইসিএ" দ্বারা স্বাক্ষরিত হতে পারে এবং সার্ভারটি আপনার ক্লায়েন্টকে মূল সিএ "আরসিএ" দিয়ে উপস্থাপন করতে পারে এবং আইসিএ দ্বারা আরসিএ নয় স্বাক্ষরিত সত্ত্বেও আপনার ওয়েব ব্রাউজার আপনাকে আপনার শংসাপত্র বাছাই করতে দেবে।
কাইলএম

2
উপরের মন্তব্যের উদাহরণ হিসাবে, আপনার এমন একটি পরিস্থিতি বিবেচনা করুন যেখানে আপনার কাছে একটি মূল সিএ (আরসিএ 1) এবং দুটি মধ্যবর্তী সিএ (আইসিএ 1 এবং আইসিএ 2) রয়েছে। অ্যাপাচি টমক্যাটে আপনি যদি আরসিএ 1 ট্রাস্ট স্টোরে আমদানি করেন তবে আপনার ওয়েব ব্রাউজারটি আপনার বিশ্বাসের দোকানে না থাকলেও, আইসিএ 1 এবং আইসিএ 2 স্বাক্ষরিত সমস্ত শংসাপত্র উপস্থাপন করবে। কারণ এটি শৃঙ্খলা যা পৃথক শংসাপত্রের জন্য গুরুত্বপূর্ণ নয়।
কাইলম

2
"আমার মতে এটি একটি অদ্ভুত আচরণ, তবে আমি নিশ্চিত যে এর কারণ রয়েছে"। এর কারণ হ'ল এটি এটি আরএফসি 2246-এ বলে। ক্লায়েন্টদের শংসাপত্রগুলি উপস্থাপনের অনুমতি দেওয়া যা সার্ভারের দ্বারা গৃহীত হবে না তা হ'ল অদ্ভুত এবং সময় এবং স্থানের সম্পূর্ণ অপচয়।
লার্নের মারকুইস

1
আপনার উপরের উদাহরণটিতে যেমন আছে আমি একক, জেভিএম-প্রশস্ত কীস্টোর (এবং ট্রস্টস্টোর!) ব্যবহারের বিরুদ্ধে অত্যন্ত পরামর্শ দিই। একটি একক সংযোগ কাস্টমাইজ করা নিরাপদ এবং আরও নমনীয়, তবে এটির জন্য আপনাকে আরও কিছু কোড লিখতে হবে। আপনি SSLContext@ ম্যাগনাসের উত্তর হিসাবে কাস্টমাইজ করতে হবে ।
ক্রিস্টোফার শুল্টজ

63

অন্যান্য উত্তরগুলি কীভাবে বিশ্বব্যাপী ক্লায়েন্টের শংসাপত্রগুলি কনফিগার করতে পারে তা দেখায়। তবে আপনি যদি আপনার JVM- র উপর চলমান প্রতিটি অ্যাপ্লিকেশন জুড়ে বিশ্বব্যাপী এটি সংজ্ঞায়িত করার পরিবর্তে কোনও নির্দিষ্ট সংযোগের জন্য ক্লায়েন্ট কীটি প্রোগ্রামিয়ালি সংজ্ঞায়িত করতে চান তবে আপনি নিজের নিজস্ব এসএসএল কনটেক্সটটি কনফিগার করতে পারেন:

String keyPassphrase = "";

KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream("cert-key-pair.pfx"), keyPassphrase.toCharArray());

SSLContext sslContext = SSLContexts.custom()
        .loadKeyMaterial(keyStore, null)
        .build();

HttpClient httpClient = HttpClients.custom().setSSLContext(sslContext).build();
HttpResponse response = httpClient.execute(new HttpGet("https://example.com"));

আমাকে ব্যবহার করতে হয়েছিল sslContext = SSLContexts.custom().loadTrustMaterial(keyFile, PASSWORD).build();। আমি এটি দিয়ে কাজ করতে পারি না loadKeyMaterial(...)
কনর সোভেনসন

4
@ কনসরসভেনসন ট্রাস্ট উপাদানটি ক্লায়েন্টের জন্য রিমোট সার্ভার শংসাপত্রের উপর নির্ভর করে, মূল উপাদানটি ক্লায়েন্টকে বিশ্বাস করা সার্ভারের জন্য।
ম্যাগনাস

1
আমি এই সংক্ষিপ্ত এবং অন-পয়েন্ট উত্তরটি সত্যিই পছন্দ করি। লোকেরা যদি আগ্রহী হয় তবে আমি এখানে বিল্ড নির্দেশাবলীর সাথে একটি কাজের উদাহরণ সরবরাহ করি। স্ট্যাকওভারফ্লো.com
আলাইন ও'ডিয়া

3
তুমি আমার দিন বাঁচিয়েছ! আমাকে আরও একটি পরিবর্তন করতে হয়েছিল, পাসওয়ার্ডটি কোডেও প্রেরণ করুন loadKeyMaterial(keystore, keyPassphrase.toCharArray())!
আনন্দশঙ্ঘব

1
@ পেটার হ্যাঁ এটি অ্যাপাচি http- তে নির্দিষ্ট। প্রতিটি এইচটিটিপি লাইব্রেরির কনফিগার করার নিজস্ব উপায় থাকবে তবে তাদের বেশিরভাগেরই কোনওরকম একটি ব্যবহার করা উচিত SSLContext
ম্যাগনাস

30

তারা জে কেএস ফাইল শংসাপত্র এবং কী জোড়ার জন্য কেবল একটি ধারক। ক্লায়েন্ট-পাশ প্রমাণীকরণের দৃশ্যে, কীগুলির বিভিন্ন অংশ এখানে অবস্থিত হবে:

  • ক্লায়েন্ট এর দোকান ক্লায়েন্টের উপস্থিত থাকবে প্রাইভেট এবং পাবলিক কী জোড়া। একে কীস্টোর বলা হয় ।
  • সার্ভার এর দোকান ক্লায়েন্টের উপস্থিত থাকবে প্রকাশ্য কী। একে ট্রস্টস্টোর বলা হয় ।

ট্রস্টস্টোর এবং কীস্টোর পৃথকীকরণ বাধ্যতামূলক নয় তবে প্রস্তাবিত। তারা একই শারীরিক ফাইল হতে পারে।

দুটি স্টোরের ফাইল সিস্টেমের অবস্থানগুলি সেট করতে, নিম্নলিখিত সিস্টেমের বৈশিষ্ট্যগুলি ব্যবহার করুন:

-Djavax.net.ssl.keyStore=clientsidestore.jks

এবং সার্ভারে:

-Djavax.net.ssl.trustStore=serversidestore.jks

ক্লায়েন্টের শংসাপত্র (পাবলিক কী) কোনও ফাইলে রফতানি করতে, যাতে আপনি এটি সার্ভারে অনুলিপি করতে পারেন, ব্যবহার করুন

keytool -export -alias MYKEY -file publicclientkey.cer -store clientsidestore.jks

সার্ভারের কীস্টোরে ক্লায়েন্টের পাবলিক কী আমদানি করতে, ব্যবহার করুন (পোস্টার উল্লিখিত হিসাবে, এটি ইতিমধ্যে সার্ভার প্রশাসকদের দ্বারা সম্পন্ন হয়েছে)

keytool -import -file publicclientkey.cer -store serversidestore.jks

আমার সম্ভবত উল্লেখ করা উচিত যে সার্ভারের উপর আমার কোনও নিয়ন্ত্রণ নেই। সার্ভারটি আমাদের সর্বজনীন শংসাপত্র আমদানি করেছে। আমাকে সেই সিস্টেমের প্রশাসকদের দ্বারা বলা হয়েছে যে আমাকে স্পষ্টভাবে শংসাপত্র সরবরাহ করা দরকার যাতে এটি হ্যান্ডশেকের সময় পাঠানো যেতে পারে (তাদের সার্ভারটি স্পষ্টভাবে এটি অনুরোধ করে))
tmbrggmn

আপনার সার্বজনীন শংসাপত্রের জন্য আপনার একটি সার্বজনীন এবং ব্যক্তিগত কী প্রয়োজন হবে (এটি সার্ভারের সাথে পরিচিত) এটি জেকেএস ফাইল হিসাবে।
sfussnegger

উদাহরণ কোডের জন্য ধন্যবাদ। উপরের কোডে, "মাইকি-পাবলিক.সিসার" হুবহু কী? এটি কি ক্লায়েন্টের সার্বজনীন শংসাপত্র (আমরা স্ব-স্বাক্ষরিত শংসাপত্রগুলি ব্যবহার করি)?
tmbrggmn

হ্যাঁ এটি হ'ল, আমি সেই অনুযায়ী কোড স্নিপেটে ফাইলগুলির নামকরণ করেছি। আমি আশা করি এটি পরিষ্কার হয়ে গেছে।
মহল্লার

রাইটো, ধন্যবাদ আমি বিভ্রান্ত হতে থাকি কারণ আপাতদৃষ্টিতে "কী" এবং "শংসাপত্র" পরস্পরের পরিবর্তে ব্যবহৃত হয়।
tmbrggmn

10

ম্যাভেন পম.এক্সএমএল:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>some.examples</groupId>
    <artifactId>sslcliauth</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>sslcliauth</name>
    <dependencies>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.4</version>
        </dependency>
    </dependencies>
</project>

জাভা কোড:

package some.examples;

import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.http.entity.InputStreamEntity;

public class SSLCliAuthExample {

private static final Logger LOG = Logger.getLogger(SSLCliAuthExample.class.getName());

private static final String CA_KEYSTORE_TYPE = KeyStore.getDefaultType(); //"JKS";
private static final String CA_KEYSTORE_PATH = "./cacert.jks";
private static final String CA_KEYSTORE_PASS = "changeit";

private static final String CLIENT_KEYSTORE_TYPE = "PKCS12";
private static final String CLIENT_KEYSTORE_PATH = "./client.p12";
private static final String CLIENT_KEYSTORE_PASS = "changeit";

public static void main(String[] args) throws Exception {
    requestTimestamp();
}

public final static void requestTimestamp() throws Exception {
    SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(
            createSslCustomContext(),
            new String[]{"TLSv1"}, // Allow TLSv1 protocol only
            null,
            SSLConnectionSocketFactory.getDefaultHostnameVerifier());
    try (CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(csf).build()) {
        HttpPost req = new HttpPost("https://changeit.com/changeit");
        req.setConfig(configureRequest());
        HttpEntity ent = new InputStreamEntity(new FileInputStream("./bytes.bin"));
        req.setEntity(ent);
        try (CloseableHttpResponse response = httpclient.execute(req)) {
            HttpEntity entity = response.getEntity();
            LOG.log(Level.INFO, "*** Reponse status: {0}", response.getStatusLine());
            EntityUtils.consume(entity);
            LOG.log(Level.INFO, "*** Response entity: {0}", entity.toString());
        }
    }
}

public static RequestConfig configureRequest() {
    HttpHost proxy = new HttpHost("changeit.local", 8080, "http");
    RequestConfig config = RequestConfig.custom()
            .setProxy(proxy)
            .build();
    return config;
}

public static SSLContext createSslCustomContext() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, KeyManagementException, UnrecoverableKeyException {
    // Trusted CA keystore
    KeyStore tks = KeyStore.getInstance(CA_KEYSTORE_TYPE);
    tks.load(new FileInputStream(CA_KEYSTORE_PATH), CA_KEYSTORE_PASS.toCharArray());

    // Client keystore
    KeyStore cks = KeyStore.getInstance(CLIENT_KEYSTORE_TYPE);
    cks.load(new FileInputStream(CLIENT_KEYSTORE_PATH), CLIENT_KEYSTORE_PASS.toCharArray());

    SSLContext sslcontext = SSLContexts.custom()
            //.loadTrustMaterial(tks, new TrustSelfSignedStrategy()) // use it to customize
            .loadKeyMaterial(cks, CLIENT_KEYSTORE_PASS.toCharArray()) // load client certificate
            .build();
    return sslcontext;
}

}

যদি আপনার পরিবর্তে কোনও নির্দিষ্ট জেভিএম ইনস্টলেশন ব্যবহার করে এমন সমস্ত অ্যাপ্লিকেশনগুলির কাছে শংসাপত্রের উপস্থিতি থাকে তবে পরিবর্তে এই উত্তরটি অনুসরণ করুন।
ADTC

configureRequest()ক্লায়েন্ট প্রকল্পের প্রক্সি সেট করার পদ্ধতিটি কি সঠিক?
শরীফ

হ্যাঁ, এটি http ক্লায়েন্ট কনফিগারেশন এবং এটি এই ক্ষেত্রে প্রক্সি কনফিগারেশন
কিনজেলম

হতে পারে আমার কাছে বোবা প্রশ্ন আছে তবে আমি কীভাবে ফাইল cacert.jks তৈরি করব? থ্রেড "মূল" java.io.FileNotFoundException:। \ Cacert.jks (সিস্টেমটি নির্দিষ্ট করা ফাইলটি খুঁজে পাচ্ছে না)
প্যাট্লাস

6

আপনারা যারা কেবল দ্বি-মুখী প্রমাণীকরণ (সার্ভার এবং ক্লায়েন্ট শংসাপত্র) সেট করতে চান তাদের জন্য, এই দুটি লিঙ্কের সংমিশ্রণটি আপনাকে সেখানে পাবেন:

দ্বি-মুখী লেখক সেটআপ:

https://linuxconfig.org/apache-web-server-ssl-authentication

তারা উল্লিখিত ওপেনসেল কনফিগারেশন ফাইল ব্যবহার করার দরকার নেই; শুধু ব্যবহার

  • $ ওপেনসেল জেনার্সা -ডেস 3-আউট Ca.key 4096

  • $ ওপেনসেল রেকিউ-নতুন -x509 -দিন 365 -কি সিএ -কি-আউট সিএ সিআরটি

আপনার নিজস্ব সিএ শংসাপত্র তৈরি করতে এবং তারপরে সার্ভার এবং ক্লায়েন্ট কীগুলি উত্পন্ন এবং স্বাক্ষর করে:

  • $ ওপেনসেল জেনার্সা -ডেস 3-আউট সার্ভার.কি 4096

  • $ ওপেনসেল রেকিউ-নতুন-কি সার্ভার.কি-আউট সার্ভার সিএসএসআর

  • $ ওপেনএসএল x509 -আরকি-ডেডস 365 -র সার্ভার সিএসআর-সিএ সিআরসিআরটি-কেকি সিএকি-সেট_সিরিয়াল 100-আউট সার্ভার সিআরটি

এবং

  • $ ওপেনসেল জেনার্সা -ডেস 3-আউট ক্লায়েন্ট.কি 4096

  • $ ওপেনসেল রেকউ-নতুন-কী ক্লায়েন্ট.কি-আউট ক্লায়েন্ট সিএসআর

  • $ ওপেনসেল x509 -আরকি-ডেডস 365 -ইন ক্লায়েন্ট সিএসআর-সিএ সিআরসিআরটি-কেকি সিএকি-সেট_সিরিয়াল 101-আউট ক্লায়েন্ট সিআরটি

বাকিদের জন্য লিঙ্কের পদক্ষেপগুলি অনুসরণ করুন। Chrome এর জন্য শংসাপত্রগুলি পরিচালনা করা যেমন উল্লেখ করা ফায়ারফক্সের উদাহরণ হিসাবে কাজ করে।

এর পরে, এর মাধ্যমে সার্ভারটি সেটআপ করুন:

https://www.digitalocean.com/community/tutorials/how-to-create-a-ssl-certificate-on-apache-for-ubuntu-14-04

নোট করুন যে আপনি ইতিমধ্যে .crt এবং .key সার্ভার তৈরি করেছেন যাতে আপনাকে আর এই পদক্ষেপটি আর করতে হবে না।


1
ভেবে দেখুন আপনার সার্ভার সিএসআর প্রজন্মের ধাপে টাইপ রয়েছে: ব্যবহার করা উচিত server.keyনয়client.key
দ্য কিংডম

0

আমি স্প্রিং বুটের সাথে দ্বিমুখী এসএসএল (ক্লায়েন্ট এবং সার্ভার শংসাপত্র) দিয়ে ব্যাঙ্কের সাথে সংযুক্ত হয়েছি। সুতরাং এখানে আমার সমস্ত পদক্ষেপগুলি বর্ণনা করুন, আশা করি এটি কাউকে সহায়তা করবে (সবচেয়ে সহজ সমাধান সমাধান, আমি খুঁজে পেয়েছি):

  1. সার্টিফিকেট অনুরোধ উত্পন্ন করুন:

    • ব্যক্তিগত কী উত্পন্ন করুন:

      openssl genrsa -des3 -passout pass:MY_PASSWORD -out user.key 2048
    • শংসাপত্রের অনুরোধ উত্পন্ন করুন:

      openssl req -new -key user.key -out user.csr -passin pass:MY_PASSWORD

    user.key(এবং পাসওয়ার্ড) রাখুন এবং user.csrআমার সার্টিফিকেটের জন্য ব্যাংকে শংসাপত্রের অনুরোধ প্রেরণ করুন

  2. 2 শংসাপত্র গ্রহণ করুন: আমার ক্লায়েন্টের রুট শংসাপত্র clientId.crtএবং ব্যাংক মূল শংসাপত্র:bank.crt

  3. জাভা কীস্টোর তৈরি করুন (কী পাসওয়ার্ড দিন এবং কীস্টোরের পাসওয়ার্ড সেট করুন):

    openssl pkcs12 -export -in clientId.crt -inkey user.key -out keystore.p12 -name clientId -CAfile ca.crt -caname root

    আউটপুট উপর মনোযোগ দিতে না: unable to write 'random state'। জাভা পিকেসিএস 12 keystore.p12তৈরি হয়েছে।

  4. কীস্টোরে যুক্ত করুন bank.crt(সরলতার জন্য আমি একটি কীস্টোর ব্যবহার করেছি):

    keytool -import -alias banktestca -file banktestca.crt -keystore keystore.p12 -storepass javaops

    কীস্টোর শংসাপত্রগুলি এর দ্বারা চেক করুন:

    keytool -list -keystore keystore.p12
  5. জাভা কোডের জন্য প্রস্তুত :) আমি যুক্ততা নির্ভরতা RestTemplateসহ স্প্রিং বুট ব্যবহার করেছি org.apache.httpcomponents.httpcore:

    @Bean("sslRestTemplate")
    public RestTemplate sslRestTemplate() throws Exception {
      char[] storePassword = appProperties.getSslStorePassword().toCharArray();
      URL keyStore = new URL(appProperties.getSslStore());
    
      SSLContext sslContext = new SSLContextBuilder()
            .loadTrustMaterial(keyStore, storePassword)
      // use storePassword twice (with key password do not work)!!
            .loadKeyMaterial(keyStore, storePassword, storePassword) 
            .build();
    
      // Solve "Certificate doesn't match any of the subject alternative names"
      SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
    
      CloseableHttpClient client = HttpClients.custom().setSSLSocketFactory(socketFactory).build();
      HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(client);
      RestTemplate restTemplate = new RestTemplate(factory);
      // restTemplate.setMessageConverters(List.of(new Jaxb2RootElementHttpMessageConverter()));
      return restTemplate;
    }

আপনি কীটোল দিয়ে এটি সব করতে পারেন। একেবারে ওপেনএসএসএলের কোনও প্রয়োজন নেই।
লার্নের মারকুইস

0

শংসাপত্র এবং প্রাইভেট কী উভয় দিয়ে একটি পি 12 ফাইল দেওয়া হয়েছে (উদাহরণস্বরূপ ওপেনসেল দ্বারা উত্পন্ন), নিম্নলিখিত কোডটি একটি নির্দিষ্ট এইচটিটিএসএল URL সংযোগের জন্য এটি ব্যবহার করবে:

    KeyStore keyStore = KeyStore.getInstance("pkcs12");
    keyStore.load(new FileInputStream(keyStorePath), keystorePassword.toCharArray());
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    kmf.init(keyStore, keystorePassword.toCharArray());
    SSLContext ctx = SSLContext.getInstance("TLS");
    ctx.init(kmf.getKeyManagers(), null, null);
    SSLSocketFactory sslSocketFactory = ctx.getSocketFactory();

    HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
    connection.setSSLSocketFactory(sslSocketFactory);

SSLContext, আরম্ভ করতে কিছু সময় লাগে তাই আপনি এটি ক্যাশে করতে চাইতে পারেন।


-1

আমি মনে করি যে এখানে ফিক্সটি মূল স্টোর টাইপ ছিল, pkcs12 (pfx) সর্বদা ব্যক্তিগত কী থাকে এবং জেকেএস প্রকারটি ব্যক্তিগত কী ছাড়া থাকতে পারে without আপনি নিজের কোডটিতে উল্লেখ না করে বা ব্রাউজারের মাধ্যমে একটি শংসাপত্র নির্বাচন না করলে সার্ভারের কাছে অন্য প্রান্তে ক্লায়েন্টকে প্রতিনিধিত্ব করছে তা জানার কোনও উপায় নেই।


1
পিকেসিএস 12 ফর্ম্যাটটি প্রথাগতভাবে প্রাইভেটকি-অ্যান্ড-সার্টের জন্য ব্যবহৃত হয়েছিল, তবে জাভা 2014 সালে 8 সাল থেকে (এই উত্তরের এক বছরেরও বেশি সময় আগে) পিকেসিএস 12 সমর্থন করেছে প্রাইভেটকি (গুলি) ছাড়াই সার্টি (গুলি) রয়েছে। কীস্টোর ফর্ম্যাট নির্বিশেষে, ক্লায়েন্ট লেখার জন্য প্রাইভেটকি-ও-সার্টের দরকার নেই। আমি তোমার দ্বিতীয় বাক্যে বুঝতে পারছি না, কিন্তু জাভা ক্লায়েন্ট করতে স্বয়ংক্রিয়ভাবে একটি ক্লায়েন্ট যা নিশ্চিতভাবে ঘটবে-এবং-কি নির্বাচন যদি অন্তত একটি উপযুক্ত এন্ট্রি পাওয়া যায় বা keymanager করতে একটি নির্দিষ্ট একটি ব্যবহার করার জন্য কনফিগার করা।
ডেভ_থমসসন_085

আপনার দ্বিতীয় বাক্যটি সম্পূর্ণ ভুল। সার্ভারটি তার বিশ্বস্ত স্বাক্ষরকারীদের সরবরাহ করে এবং ক্লায়েন্ট হয় হয় মারা যায় বা কোনও শংসাপত্র সরবরাহ করে না যা সেই সীমাবদ্ধতা পূরণ করে। স্বয়ংক্রিয়ভাবে, আপনার কোডের মাধ্যমে নয়। যে হয় সার্ভারের 'বুদ্ধিমান একটি ক্লায়েন্ট প্রতিনিধিত্ব করছে প্রণালী'।
লার্নের মারকুইস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.