پیکربندی امنیت شبکه در اندروید

یکی از ویژگی های سیستم عامل اندروید، Network Security Configuration است که به اپلیکیشن ها اجازه میدهد تنظیمات امنیت شبکه خودشان را در یک فایل ایمن، بدون نیاز به دستکاری بقیه کدها  شخصی سازی کنند. این تنظیمات میتوانند برای دامنه ها یا اپلیکیشن های خاص اعمال بشوند. در این نوشته از بلاگ برنامه چی همه تنظیمات پیکربندی امنیت شبکه را با هم بررسی میکنیم. با ما همراه باشید.

پیکربندی امنیت شبکه در اندروید

اگر دنبال یک خلاصه از همه این نوشته هستید، باید این را بدانید که با اضافه کردن یک فایل XML در آدرس res/xml به نام network_security_config.xml شما میتوانید ارتباطات اپلیکیشن خودتان را کنترل کنید. این مقاله همه کارهایی که میتوانید با این فایل انجام بدهید و ساختار آن را به شما معرفی خواهد کرد. لیست تیتر ها را میتوانید در کادر زیر مشاهده کنید.


با پیکربندی امنیت شبکه چه کارهایی میتوان کرد؟

شما میتوانید با پیکربندی امنیت شبکه در اندروید، ترافیک و ارتباطات اپلیکیشن خودتان را مدیریت کنید. علاوه بر اینها یک سری امکانات سفارشی در اختیار شما قرار دارد که میتوانید آنها را در ادامه مشاهده کنید:

  • لینک های امنیتی دلخواه: میتوانید تعیین کنید که کدام Certificate Authoritiy یا CA برای ارتباط ایمن اپلیکیشن مورد اعتماد است. به عنوان مثال، برای اعتماد به گواهینامه های Self-Signed یا محدود کردن اعتماد اپلیکیشن به یک مجموعه مشخص از CA های عمومی.
  • فعال کردن قابلیت Debug-only: میتوانید ارتباطات امن را در یک محیط ایمن اشکال زدایی کنید، بدون اینکه به اپلیکیشنی که نصب شده آسیبی بزنید.
  • انصراف از Cleartext: این قابلیت را دارید که اپلیکیشن را از استفاده ناخواسته ترافیک Cleartext محافظت کنید.
  • پین کردن گواهینامه: میتوانید ارتباطات امن یک اپلیکیشن را به گواهینامه های خاص محدود کنید.

اضافه کردن یک فایل Network Security Configuration

فایل network security configuration

برای استفاده از قابلیت کانفیگ امنیت شبکه در اندروید (یعنی همان Network Security Configuration) باید یک فایل xml درست کنیم که در این فایل، تنظیمات مورد نظر برای اپلیکیشن را تعریف میکنیم. همچنین باید این فایل را در Manifest اپلیکیشن هم قرار بدهیم. در تکه کد زیر نحوه معرفی در فایل Manifest را مشاهده میکنیم:

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:networkSecurityConfig="@xml/network_security_config"
                    ... >
        ...
    </application>
</manifest>

شخصی سازی CA های مورد اعتماد

ممکن است یک اپلیکیشن نیاز داشته باشد به CA های خاصی، به جز موارد پیشفرض اندروید اعتماد کند. اصلی ترین دلایل این کار میتوانید این ها باشد:

  • اتصال به یک هاست که CA شناخته شده ای ندارد، مانند CA هایی که Self-Signed هستند یا بصورت درونی کمپانی های مختلف استفاده میشوند.
  • محدود کردن CA های قابل اعتماد به مجموعه ای از CA ها که به آنها اعتماد دارید.
  • اعتماد کردن به CA هایی درون سیستم قرار داده نشده اند.
ca های مورد اعتماد پیکربندی امنیت شبکه

بصورت پیشفرض، ارتباط های ایمن (یعنی آن هایی که از پروتکل هایی مانند TLS و HTTPS استفاده میکنند) در همه اپلیکیشن ها، به CA های از پیش نصب شده در سیستم اعتماد میکنند. همچنین اپلیکیشن هایی که برای ورژن 6.0 اندروید (API 23) به پایین ساخته شده اند، به همه CA هایی که کاربر بصورت دستی اضافه کرده نیز اعتماد میکنند. یک اپلیکیشن میتواند با استفاده از base-config (برای شخصی سازی ارتباطات اپلیکیشن) یا domain-config (برای شخصی سازی روی هر دامنه) ارتباطات خودش را تغییر بدهد.


پیکربندی یک CA سفارشی

فرض کنید میخواهید به یک هاست متصل شوید که گواهینامه آن Self-Signed است، یا یک هاست که CA آن بصورت عمومی در دسترس نیست ولی شما به آن اعتماد دارید، مانند CA داخلی شرکت خودتان. فایل زیر در آدرس res/xml اضافه شده و محتویات آن را میتوانید در ادامه مشاهده کنید.

فایل: res/xml/network_security_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">example.com</domain>
        <trust-anchors>
            <certificates src="@raw/my_ca"/>
        </trust-anchors>
    </domain-config>
</network-security-config>

بعد از این کار باید گواهینامه Self-Signed یا غیر عمومی خودتان را به فرمت های PEM یا DER به فایلی با آدرس زیر اضافه کنید:

res/raw/my_ca


محدود کردن مجموعه CA های مورد اعتماد

اپلیکیشنی که نمیخواهد به همه CA های تعریف شده در سیستم اعتماد کند، میتواند یک مجموعه CA قابل اعتماد برای خودش بسازد. این کار اپلیکیشن شما را از گواهینامه های جعلی که ممکن است توسط بقیه CA ها صادر شده باشد، محافظت میکند.

پیکربندی مورد نیاز برای محدود کردن مجموعه CA های موردی اعتماد، شبیه به اعتماد کردن به یک CA سفارشی برای یک دامنه خاص است، با این تفاوت که باید چندین CA در فایل مورد نظر تعریف کنیم. مثال زیر را مشاهده کنید:

فایل: res/xml/network_security_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">secure.example.com</domain>
        <domain includeSubdomains="true">cdn.example.com</domain>
        <trust-anchors>
            <certificates src="@raw/trusted_roots"/>
        </trust-anchors>
    </domain-config>
</network-security-config>

بعد از این کار باید CA های مورد اعتماد را با فرمت های PEM یا DER به فایل زیر اضافه کنید:

res/raw/trusted_roots

دقت داشته باشید که اگر از فرمت PEM میخواهید استفاده کنید، همه CA های درون سایت باید فرمت PEM داشته باشند و درون فایل نباید هیچ متن اضافه ای وجود داشته باشد. همچنین میتوانید به جای یک عدد، چندین المان <certificate> تعریف کنید.


اعتماد به CA های اضافه

یک اپلیکیشن ممکن است بخواهد به CA هایی اعتماد کند که هنوز توسط سیستم عامل قابل اعتماد نیستند. این اتفاق ممکن است زمانی رخ بدهد که CA تازه شروع به کار کرده و هنوز در سیستم عامل اندروید موجود نیست. یا اینکه CA مورد نظر دارای شرایط لازم برای قرار گرفتن در پلتفرم اندروید نبوده است. اپلیکیشن میتواند برای انجام این کار، منابع مختلف صدور گواهینامه را در فایل پیکربندی قرار بدهد:

فایل: res/xml/network_security_config.xml

&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;network-security-config&gt;
    &lt;base-config&gt;
        &lt;trust-anchors&gt;
            &lt;certificates src="@raw/extracas"/&gt;
            &lt;certificates src="system"/&gt;
        &lt;/trust-anchors&gt;
    &lt;/base-config&gt;
&lt;/network-security-config&gt;

پیکربندی CA ها برای مشکل زدایی

دیباگ پیکربندی امنیت شبکه در اندروید

در زمان توسعه و Debug کردن یک پروژه که از پروتکل HTTPS استفاده میکند، ممکن است برای تست های مختلف نیاز داشته باشید به یک سرور داخلی، که فاقد گواهینامه SSL است متصل شوید. برای اینکه بدون تغییر دادن کدهای اپلیکیشن خودتان بتوانید همچین کاری کنید، باید CA های مخصوص اشکال زدایی (Debug-Only) را به پیکربندی امنیت شبکه اضافه کنید. این CA ها فقط زمانی مورد اعتماد قرار میگیرند که ویژگی android:debuggable برابر با true باشد. این کار را میتوانید با استفاده از debug-override انجام بدهید. معمولا IDE ها این پرچم را برای بیلدهای non-released بصورت اتوماتیک تنظیم میکنند.

نکته: این راهکار معمولا از تعریف این flag با استفاده از کدهای شرطی، ایمن تر است. زیرا اپ استور ها اپلیکیشن هایی که debuggable باشند را نمیپذیرند.

فایل: res/xml/network_security_config.xml

&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;network-security-config&gt;
    &lt;debug-overrides&gt;
        &lt;trust-anchors&gt;
            &lt;certificates src="@raw/debug_cas"/&gt;
        &lt;/trust-anchors&gt;
    &lt;/debug-overrides&gt;
&lt;/network-security-config&gt;

انصراف از ترافیک Cleartext

network security config http

نکته: دستورالعمل هایی که در این قسمت وجود دارند فقط برای اپلیکیشن هایی که اندروید 8.1 (API 27) به پایین را پشتیبانی میکنند، قابل استفاده اند. از اندروید 9 (API 28) به بعد، پشتیبانی از Cleartext بصورت پیشفرض غیرفعال شده است

اگر اپلیکیشن قصد دارد به سرور هایی متصل شود که فقط از ارتباط ایمن پشتیبانی میکنند، میتواند پشتیبانی از ترافیک Cleartext (یعنی استفاده از پروتکل HTTP به جای HTTPS که رمزگذاری نشده است) را متوقف کند. این قابلیت، اپلیکیشن را از ترافیک های ناخواسته که ممکن است در اثر تغییرات سرور رخ بدهد محافظت میکند.

برای مثال، یک اپلیکیشن شاید بخواهد مطمئن شود که همه ارتباطات با secure.example.com همیشه با HTTPS انجام میشوند تا ترافیک حساس را محافظت کنند.

فایل: res/xml/network_security_config.xml

&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;network-security-config&gt;
    &lt;domain-config cleartextTrafficPermitted="false"&gt;
        &lt;domain includeSubdomains="true"&gt;secure.example.com&lt;/domain&gt;
    &lt;/domain-config&gt;
&lt;/network-security-config&gt;

Pin کردن گواهینامه ها

بصورت نرمال، یک اپلیکیشن به همه CA های از قبل نصب شده در سیستم عامل اعتماد میکند. اگر یکی از این CA ها گواهینامه جعلی تولید کند، اپلیکیشن در معرض خطر هک شدن (man-in-the-middle Attack) قرار میگیرد. بعضی اپلیکیشن ها مجموعه گواهینامه های قابل قبول خودشان را با محدود کردن CA های قابل اعتماد، کنترل میکنند. این کار با Pin کردن گواهینامه هم قابل انجام است.

برای Pin کردن یک گواهینامه، باید مجموعه گواهینامه ها به همراه Hash کلید عمومی آن ها را تهیه کنیم (یعنی SubjectPublicKeyInfo از گواهینامه X.509). بعد از این کار، یک زنجیره از گواهینامه ها فقط زمانی معتبر هستند که حداقل یکی از گواهینامه های این زنجیره، شامل یکی از گواهینامه های Pin شده باشد.

این نکته را در نظر داشته باشید که وقتی گواهینامه ها را Pin میکنید، همیشه باید یک کلید بکاپ هم داشته باشید. در این صورت اگر مجبور شوید کلید های جدید استفاده کنید یا CA ها را عوض کنید، ارتباطات اپلیکیشن شما از بین نخواهند رفت. اگر بکاپ نداشته باشید، برای درست کردن کانکشن اپلیکیشن، باید یک آپدیت ارائه بدهید.

علاوه بر اینها، شما میتوانید زمان انقضا برای گواهینامه های Pin شده تعریف کنید، که بعد از این زمان، گواهینامه های مورد نظر دیگر Pin شده باقی نمی مانند. وقتی که هیچ گواهینامه ای Pin نباشد، یعنی اپلیکیشن بصورت عادی به همه CA های پیشفرض پلتفرم اعتماد خواهد کرد. این قابلیت برای اپلیکیشن هایی که آپدیت نمیشوند مفید است و باعث میشود مشکلات ارتباطی برای آنها به وجود نیاید. اما به هر حال، استفاده از این ویژگی ممکن است باعث فعال شدن Pinning Bypass بشود (یعنی دور زدن گواهینامه های Pin شده).

فایل: res/xml/network_security_config.xml

&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;network-security-config&gt;
    &lt;domain-config&gt;
        &lt;domain includeSubdomains="true"&gt;example.com&lt;/domain&gt;
        &lt;pin-set expiration="2018-01-01"&gt;
            &lt;pin digest="SHA-256"&gt;7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=&lt;/pin&gt;
            &lt;!-- backup pin --&gt;
            &lt;pin digest="SHA-256"&gt;fwza0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1oE=&lt;/pin&gt;
        &lt;/pin-set&gt;
    &lt;/domain-config&gt;
&lt;/network-security-config&gt;

ارث بری پیکربندی

مقادیری که در پیکربندی تعریف نشده باشند، از سیستم به ارث میرسند. این رفتار به ما اجازه میدهد پیکربندی پیچیده تری داشته باشیم، در حالیکه فایل پیکربندی امنیت شبکه همچنان قابل خواندن باقی خواهد ماند.

اگر یکی از مقادیر در فایل پیکر بندی وجود نداشته باشد، این مقادیر از معمولی ترین ورودی های موجود دریافت خواهند شد. به عنوان مثال، اگر مقدار خاصی برای domain-config وارد نکرده باشیم، مقدار آن از در صورت وجود از domain-config والد و اگر وجود نداشت، از base-config گرفته خواهد شد. اگر مقادیر خاصی در base-config وجود نداشته باشد، از اطلاعات پیشفرض پلتفرم استفاده خواهد شد.

برای مثال، سناریویی را فرض کنید که همه ارتباطات به ساب دامنه های example.com باید از یک سری CA سفارشی استفاده کنند. علاوه بر این، استفاده از ترافیک Cleartext برای این ساب دامنه ها، بجز secure.example.com مجاز است. با توجه به مواردی که گفته شد و به عنوان راه حل، اگر پیکربندی های مربوط به secure.example.com را درون پیکربندی مخصوص به example.com قرار بدهیم، دیگر نیاز ندارید trust-anchors را کپی کنید. کدهای زیر را مشاهده کنید:

فایل: res/xml/network_security_config.xml

&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;network-security-config&gt;
    &lt;domain-config&gt;
        &lt;domain includeSubdomains="true"&gt;example.com&lt;/domain&gt;
        &lt;trust-anchors&gt;
            &lt;certificates src="@raw/my_ca"/&gt;
        &lt;/trust-anchors&gt;
        &lt;domain-config cleartextTrafficPermitted="false"&gt;
            &lt;domain includeSubdomains="true"&gt;secure.example.com&lt;/domain&gt;
        &lt;/domain-config&gt;
    &lt;/domain-config&gt;
&lt;/network-security-config&gt;

فرمت فایل پیکربندی

فایل پیکربندی امنیت شبکه از فرمت xml پشتیبانی میکند. ساختار کلی این فایل را میتوانید در نمونه کد زیر مشاهده کنید:

&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;network-security-config&gt;
    &lt;base-config&gt;
        &lt;trust-anchors&gt;
            &lt;certificates src="..."/&gt;
            ...
        &lt;/trust-anchors&gt;
    &lt;/base-config&gt;

    &lt;domain-config&gt;
        &lt;domain&gt;android.com&lt;/domain&gt;
        ...
        &lt;trust-anchors&gt;
            &lt;certificates src="..."/&gt;
            ...
        &lt;/trust-anchors&gt;
        &lt;pin-set&gt;
            &lt;pin digest="..."&gt;...&lt;/pin&gt;
            ...
        &lt;/pin-set&gt;
    &lt;/domain-config&gt;
    ...
    &lt;debug-overrides&gt;
        &lt;trust-anchors&gt;
            &lt;certificates src="..."/&gt;
            ...
        &lt;/trust-anchors&gt;
    &lt;/debug-overrides&gt;
&lt;/network-security-config&gt;

حالا همه بخش های این ساختار را با هم بررسی میکنیم:


المان <network-security-config>

اجزای داخلی:

  • 0 یا 1 عدد <base-config>
  • هر تعداد از <domain-config>
  • 0 یا 1 عدد <debug-override>

المان <base-config>

سینتکس:

&lt;base-config cleartextTrafficPermitted=["true" | "false"]&gt;
    ...
&lt;/base-config&gt;

اجزای داخلی:

  • <trust-anchors>

توضیحات:

پیکربندی پیش فرضی که توسط همه ارتباطاتی که دارای <domain-config> نیستند، استفاده میشود. هر مقداری که در این المان تعریف نشود، با مقادیر پیشفرض پلتفرم جایگزین خواهد شد. پیکربندی پیشفرض برای اپلیکیشن های اندروید 9 (API 28) و بالاتر به این شکل است:

&lt;base-config cleartextTrafficPermitted="false"&gt;
    &lt;trust-anchors&gt;
        &lt;certificates src="system" /&gt;
    &lt;/trust-anchors&gt;
&lt;/base-config&gt;

پیکربندی پیشفرض اپلیکیشن های اندروید 7.0 (API 24) تا اندروید 8.1 (API 27) به شکل زیر است:

&lt;base-config cleartextTrafficPermitted="true"&gt;
    &lt;trust-anchors&gt;
        &lt;certificates src="system" /&gt;
    &lt;/trust-anchors&gt;
&lt;/base-config&gt;

پیکربندی پیشفرض برای اپلیکیشن های اندروید 6.0 (API 23) و پایین تر به شکل زیر است:

&lt;base-config cleartextTrafficPermitted="true"&gt;
    &lt;trust-anchors&gt;
        &lt;certificates src="system" /&gt;
        &lt;certificates src="user" /&gt;
    &lt;/trust-anchors&gt;
&lt;/base-config&gt;

المان <domain-config>

سینتکس:

&lt;domain-config cleartextTrafficPermitted=["true" | "false"]&gt;
    ...
&lt;/domain-config&gt;

اجزای داخلی:

  • 1 یا بیشتر از <domain>
  • 0 یا 1 عدد از <trust-anchors>
  • 0 یا 1 عدد از <pin-test>
  • هر تعدادی از <domain-config> تو در تو

توضیحات:

پیکربندی های مورد استفاده در ارتباطات با یک مقصد خاص، با المان <domain> تعریف میشوند. دقت داشته باشید اگر چندین المان <domain-config> برای یک مقصد تعریف شوند، المانی که طولانی ترین domain را داشته باشد مورد استفاده قرار خواهد گرفت.


المان <domain>

سینتکس:

&lt;domain includeSubdomains=["true" | "false"]&gt;example.com&lt;/domain&gt;

ویژگی ها (Attributes):

  • ویژگی includeSubdomain: اگر برابر با true باشد، آن وقت این قانون برای دامنه و همه ساب دامنه ها و حتی ساب دامنه های ساب دامنه ها اعمال خواهد شد. در غیر این صورت، قوانین فقط برای همان دامنه اعمال میشوند.

المان <debug-overrides>

سینتکس:

&lt;debug-overrides&gt;
    ...
&lt;/debug-overrides&gt;

اجزای داخلی:

  • 0 یا 1 عدد <trust-anchors>

توضیحات:

کارهایی که باید نادیده گرفته بشوند، وقتی که مقدار android:debuggable برابر با true باشد. این مقدار توسط IDE و زمانی که اپلیکیشن در حالت no-release قرار داشته باشد، تنظیم خواهد شد. مواردی که در Trust Anchors این المان وارد میکنید، به همه پیکربندی های دیگر اضافه میشوند. همچنین Pin کردن گواهینامه ها در مواقعی که زنجیره گواهینامه های سرور یکی از این Trust Anchor ها را استفاده کند، اتفاق نمی افتد. اگر مقدار android:debuggable برابر با false باشد، هیچکدام از این اتفاق ها رخ نمیدهد.


المان <trust-anchors>

سینتکس:

&lt;trust-anchors&gt;
...
&lt;/trust-anchors&gt;

اجزای داخلی:

  • هر تعداد از <certificates>

توضیحات:

مجموعه ای از Trust Anchor ها یا لینک های مطمئن برای ارتباطات ایمن.


المان <certificates>

سینتکس:

&lt;certificates src=["system" | "user" | "raw resource"]
              overridePins=["true" | "false"] /&gt;

توضیحات:

مجموعه ای از گواهینامه های X.509 برای المان trust-anchors.

ویژگی ها (Attributes):

  • src:

منبع گواهینامه های CA. هرکدام از گواهینامه ها میتواند یکی از این موارد باشد:

یک ID منبع خام که به فایلی شامل گواهینامه X.509 اشاره میکند. گواهینامه ها باید با فرمت PEM یا DER فرمت شده باشند. برای گواهینامه های PEM، فایل نباید هیچ داده اضافه دیگری (مثلا کامنت) درون خود داشته باشد.

عبارت “system” برای گواهینامه های پیشفرض پلتفرم.

عبارت “user” برای گواهینامه هایی که کاربر اضافه کرده است.


المان <pin-test>

سینتکس:

&lt;pin-set expiration="date"&gt;
...
&lt;/pin-set&gt;

اجزای داخلی:

  • هر تعداد از <pin>

توضیحات:

مجموعه ای از پین های کلید عمومی. برای اعتماد به ارتباطات ایمن، یکی از کلید های عمومی که در زنجیره اعتماد سرور هستند، باید درون مجموعه pin ها وجود داشته باشد. برای مشاهده فرمت های مناسب، المان <pin> را نگاه کنید.

ویژگی ها (Attributes):

  • expiration: تاریخ با فرمت dd-MM-yyyy که تاریخ انقضای Pin ها را مشخص میکند و بعد از این تاریخ، Pin کردن غیرفعال میشود. اگر از این ویژگی استفاده نکنید، Pin ها منقضی نمیشوند.

المان <pin>

سینتکس:

&lt;pin digest=["SHA-256"]&gt;base64 encoded digest of X.509
    SubjectPublicKeyInfo (SPKI)&lt;/pin&gt;

ویژگی ها (Attributes):

  • digest: الگوریتم تحلیلی مورد استفاده برای تولید کردن pin. در حال حاضر فقط SHA-256 را پشتیبانی میکند.

سوالی دارید؟

در این مقاله درباره پیکربندی امنیت شبکه در اندروید صحبت کردیم و اجزای مختلف آن را با هم بررسی کردیم. اگر هنوز سوالی در ذهن شما وجود دارد یا نکته ای بلد هستید، میتوانید با نوشتن آن در قسمت نظرات (همین پایین) به کامل تر کردن این مقاله آموزشی کمک کنید.


منابع بیشتر برای مطالعه

میتوانید از منابع زیر برای مطالعه بیشتر درباره پیکربندی امنیت شبکه در اندروید استفاده کنید:

درباره نویسنده

4 در مورد “پیکربندی امنیت شبکه در اندروید”

  1. مجید طالبی

    سلام ممنون از توضیحاتتون خیلی توی سایت های ایرانی و خارجی گشتم توضیحات شما عالی بودفقط یک سوال من از سرور پلسک استفاده میکنم و روی دامنه اصلی و ساب دامین هام ssl رایگان اضافه کردم و الان توی اندروید های زیر 7 مشکل SSLHandshakeException دارم از هاستم فایل x.pem رو دانلود کردم الان این فایل رو مستقیم توی پوشه raw بذارم یا پوشه raw/my_ca ممنون میشم راهنمایی کنید چند روزه درگیرم

    1. سلام و خسته نباشید خدمت شما دوست عزیز.
      ممنونم از کامنت خوبتون و انرژی مثبتی که به ما دادین.
      مهم نیست که فایل رو کجا قرار میدین. مهم آدرس دهی و نام گذاری هست که درست باشه. مطمپن بشین که نام فایل رو درست انتخاب کردین و میتونین از لینک های زیر هم کمک بگیرین براش:
      https://stackoverflow.com/questions/56166665/how-to-export-certificate-key-to-pem-format
      https://stackoverflow.com/questions/652916/converting-a-java-keystore-into-pem-format

دیدگاه‌ خود را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

اسکرول به بالا