كيف أقوم بإدراج/تصدير المفاتيح الخاصة من مخزن المفاتيح؟

StackOverflow https://stackoverflow.com/questions/150167

  •  02-07-2019
  •  | 
  •  

سؤال

كيف أقوم بإدراج وتصدير مفتاح خاص من مخزن المفاتيح؟

هل كانت مفيدة؟

المحلول

جزء من التعليمات البرمجية في الأصل من مستودع الأمثلة لإدراج جميع الأسماء المستعارة في مخزن المفاتيح:

    // Load input stream into keystore
    keystore.load(is, password.toCharArray());

    // List the aliases
    Enumeration aliases = keystore.aliases();
    for (; aliases.hasMoreElements(); ) {
        String alias = (String)aliases.nextElement();

        // Does alias refer to a private key?
        boolean b = keystore.isKeyEntry(alias);

        // Does alias refer to a trusted certificate?
        b = keystore.isCertificateEntry(alias);
    }

جاء تصدير المفاتيح الخاصة في منتديات الشمس قبل بضعة أشهر، و u:turingCompleter توصلت إلى فئة DumpPrivateKey لدمجها في تطبيقك.

import java.io.FileInputStream;
import java.security.Key;
import java.security.KeyStore;
import sun.misc.BASE64Encoder;

public class DumpPrivateKey {
     /**
     * Provides the missing functionality of keytool
     * that Apache needs for SSLCertificateKeyFile.
     *
     * @param args  <ul>
     *              <li> [0] Keystore filename.
     *              <li> [1] Keystore password.
     *              <li> [2] alias
     *              </ul>
     */
    static public void main(String[] args)
    throws Exception {
        if(args.length < 3) {
          throw new IllegalArgumentException("expected args: Keystore filename, Keystore password, alias, <key password: default same tha
n keystore");
        }
        final String keystoreName = args[0];
        final String keystorePassword = args[1];
        final String alias = args[2];
        final String keyPassword = getKeyPassword(args,keystorePassword);
        KeyStore ks = KeyStore.getInstance("jks");
        ks.load(new FileInputStream(keystoreName), keystorePassword.toCharArray());
        Key key = ks.getKey(alias, keyPassword.toCharArray());
        String b64 = new BASE64Encoder().encode(key.getEncoded());
        System.out.println("-----BEGIN PRIVATE KEY-----");
        System.out.println(b64);
        System.out.println("-----END PRIVATE KEY-----");
    }
    private static String getKeyPassword(final String[] args, final String keystorePassword)
    {
       String keyPassword = keystorePassword; // default case
       if(args.length == 4) {
         keyPassword = args[3];
       }
       return keyPassword;
    }
}

ملحوظة:هذا استخدام حزمة الشمس، وهو "شيء سيء".
إذا كنت تستطيع تحميل رمز أباتشي المشترك, ، هنا نسخة سيتم تجميعها دون سابق إنذار:

javac -classpath .:commons-codec-1.4/commons-codec-1.4.jar DumpPrivateKey.java

وسيعطي نفس النتيجة:

import java.io.FileInputStream;
import java.security.Key;
import java.security.KeyStore;
//import sun.misc.BASE64Encoder;
import org.apache.commons.codec.binary.Base64;

public class DumpPrivateKey {
     /**
     * Provides the missing functionality of keytool
     * that Apache needs for SSLCertificateKeyFile.
     *
     * @param args  <ul>
     *              <li> [0] Keystore filename.
     *              <li> [1] Keystore password.
     *              <li> [2] alias
     *              </ul>
     */
    static public void main(String[] args)
    throws Exception {
        if(args.length < 3) {
          throw new IllegalArgumentException("expected args: Keystore filename, Keystore password, alias, <key password: default same tha
n keystore");
        }
        final String keystoreName = args[0];
        final String keystorePassword = args[1];
        final String alias = args[2];
        final String keyPassword = getKeyPassword(args,keystorePassword);
        KeyStore ks = KeyStore.getInstance("jks");
        ks.load(new FileInputStream(keystoreName), keystorePassword.toCharArray());
        Key key = ks.getKey(alias, keyPassword.toCharArray());
        //String b64 = new BASE64Encoder().encode(key.getEncoded());
        String b64 = new String(Base64.encodeBase64(key.getEncoded(),true));
        System.out.println("-----BEGIN PRIVATE KEY-----");
        System.out.println(b64);
        System.out.println("-----END PRIVATE KEY-----");
    }
    private static String getKeyPassword(final String[] args, final String keystorePassword)
    {
       String keyPassword = keystorePassword; // default case
       if(args.length == 4) {
         keyPassword = args[3];
       }
       return keyPassword;
    }
}

يمكنك استخدامه مثل هذا:

java -classpath .:commons-codec-1.4/commons-codec-1.4.jar DumpPrivateKey $HOME/.keystore changeit tomcat

نصائح أخرى

يمكنك استخراج مفتاح خاص من مخزن المفاتيح باستخدام Java6 وOpenSSL.يعتمد كل هذا على حقيقة أن كلاً من Java وOpenSSL يدعمان ملفات تخزين المفاتيح بتنسيق PKCS#12.للقيام بالاستخراج، عليك أولا استخدام keytool للتحويل إلى التنسيق القياسي.تأكد أنك استخدم نفس كلمة المرور لكلا الملفين (كلمة مرور المفتاح الخاص، وليس كلمة مرور مخزن المفاتيح) أو سوف تحصل على إخفاقات غريبة في وقت لاحق في الخطوة الثانية.

keytool -importkeystore -srckeystore keystore.jks \
    -destkeystore intermediate.p12 -deststoretype PKCS12

بعد ذلك، استخدم OpenSSL لإجراء الاستخراج إلى PEM:

openssl pkcs12 -in intermediate.p12 -out extracted.pem -nodes

يجب أن تكون قادرًا على التعامل مع ملف PEM بسهولة كافية؛إنه نص عادي يحتوي على مفتاح خاص مشفر وغير مشفر وشهادة (شهادات) بداخله (بتنسيق واضح جدًا).

عند القيام بذلك، احرص على الحفاظ على أمان الملفات التي تم إنشاؤها.أنها تحتوي على أوراق اعتماد سرية.لن يحذرك أي شيء إذا فشلت في تأمينها بشكل صحيح. أسهل طريقة لتأمينها هي القيام بكل هذا في دليل لا يتمتع بأي حقوق وصول لأي شخص آخر غير المستخدم.ولا تضع كلمة المرور الخاصة بك أبدًا في سطر الأوامر أو في متغيرات البيئة؛فمن السهل جدًا على المستخدمين الآخرين الاستيلاء عليها.

إذا لم تكن بحاجة إلى القيام بذلك برمجيًا، ولكنك تريد فقط إدارة مفاتيحك، فقد استخدمت أداة KeyMan المجانية من IBM لفترة طويلة الآن.جميل جدًا لتصدير مفتاح خاص إلى ملف PFX (ثم يمكنك بسهولة استخدام OpenSSL لمعالجته واستخراجه وتغيير الأشخاص ذوي الإعاقة وما إلى ذلك).

https://www.ibm.com/developerworks/mydeveloperworks/groups/service/html/communityview?communityUuid=6fb00498-f6ea-4f65-bf0c-adc5bd0c5fcc

حدد ملف تخزين المفاتيح الخاص بك، وحدد إدخال المفتاح الخاص، ثم ملف->حفظ في ملف pkcs12 (*.pfx، عادةً).يمكنك بعد ذلك عرض المحتويات باستخدام:

$ openssl pkcs12 -in mykeyfile.pfx -info

فيما يلي نسخة أقصر من الكود أعلاه، في Groovy.يحتوي أيضًا على ترميز Base64 المدمج:

import java.security.Key
import java.security.KeyStore

if (args.length < 3)
        throw new IllegalArgumentException('Expected args: <Keystore file> <Keystore format> <Keystore password> <alias> <key password>')

def keystoreName = args[0]
def keystoreFormat = args[1]
def keystorePassword = args[2]
def alias = args[3]
def keyPassword = args[4]

def keystore = KeyStore.getInstance(keystoreFormat)
keystore.load(new FileInputStream(keystoreName), keystorePassword.toCharArray())
def key = keystore.getKey(alias, keyPassword.toCharArray())

println "-----BEGIN PRIVATE KEY-----"
println key.getEncoded().encodeBase64()
println "-----END PRIVATE KEY-----"

لتطوير Android ، لتحويل Keystore الذي تم إنشاؤه في Eclipse ADT إلى مفتاح عام ومفتاح خاص يستخدم في Signapk.jar:

تصدير المفتاح الخاص:

keytool.exe -importkeystore -srcstoretype JKS -srckeystore my-release-key.keystore -deststoretype PKCS12 -destkeystore keys.pk12.der
openssl.exe pkcs12 -in keys.pk12.der -nodes -out private.rsa.pem

قم بتحرير public.rsa.pem واترك "-----بدء المفتاح الخاص-----" إلى فقرة "-----إنهاء المفتاح الخاص-----"، ثم:

openssl.exe base64 -d -in private.rsa.pem -out private.rsa.der

تصدير المفتاح العام:

keytool.exe -exportcert -keystore my-release-key.keystore -storepass <KEYSTORE_PASSWORD> -alias alias_name -file public.x509.der

التوقيع APK:

java -jar SignApk.jar public.x509.der private.rsa.der input.apk output.apk

تم طرح هذا السؤال حول أمان تبادل المكدس، وكان أحد الاقتراحات هو استخدامه مستكشف مخزن المفاتيح

https://security.stackexchange.com/questions/3779/how-can-i-export-my-private-key-from-a-Java-keytool-keystore

بعد أن جربته للتو، فهو يعمل بشكل جيد حقًا وأوصي به بشدة.

أولا وقبل كل شيء، كن حذرا!يعتمد كل أمانك على ... إيه ... خصوصية من الخاص بك مفاتيح خاصة. لا تحتوي أداة Keytool على تصدير مفتاح مدمج لتجنب الكشف غير المقصود عن هذه المواد الحساسة، لذا قد ترغب في التفكير في بعض الضمانات الإضافية التي يمكن وضعها لحماية مفاتيحك المصدرة.

إليك بعض التعليمات البرمجية البسيطة التي تمنحك PKCS #8 PrivateKeyInfo غير المشفر الذي يمكن استخدامه بواسطة OpenSSL (راجع -nocrypt خيار لها فائدة pkcs8):

KeyStore keys = ...
char[] password = ...
Enumeration<String> aliases = keys.aliases();
while (aliases.hasMoreElements()) {
  String alias = aliases.nextElement();
  if (!keys.isKeyEntry(alias))
    continue;
  Key key = keys.getKey(alias, password);
  if ((key instanceof PrivateKey) && "PKCS#8".equals(key.getFormat())) {
    /* Most PrivateKeys use this format, but check for safety. */
    try (FileOutputStream os = new FileOutputStream(alias + ".key")) {
      os.write(key.getEncoded());
      os.flush();
    }
  }
}

إذا كنت بحاجة إلى تنسيقات أخرى، فيمكنك استخدام KeyFactory للحصول على مواصفات مفاتيح شفافة لأنواع مختلفة من المفاتيح.ثم يمكنك، على سبيل المثال، الحصول على الأس الخاص لمفتاح RSA الخاص وإخراجه بالتنسيق الذي تريده.من شأنه أن يجعل موضوعا جيدا لسؤال المتابعة.

أداة أخرى رائعة هي KeyStore Explorer: http://keystore-explorer.sourceforge.net/

هناك طريقة أخرى أقل تقليدية ولكن يمكن القول إنها أسهل للقيام بذلك وهي باستخدام JXplorer.على الرغم من أن هذه الأداة مصممة لتصفح دلائل LDAP، إلا أنها تحتوي على واجهة مستخدم رسومية سهلة الاستخدام لمعالجة مخازن المفاتيح.يمكن لإحدى هذه الوظائف في واجهة المستخدم الرسومية تصدير المفاتيح الخاصة من مخزن مفاتيح JKS.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top