Java: تنسيق Keystore غير صالح ، عند إنشاؤه من خلال التعليمات البرمجية

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

سؤال

لقد تم طلب ذلك عدة مرات ، ولكن لا شيء يوفر حالات اختبار مشفرة. هنا أعطي مثالا على المشكلة:

  1. توليد البرنامج من مفاتيح (أعمال)
  2. إنشاء شهادة داخل هذا المتجر (الأعمال)
  3. حفظ keystore إلى القرص (الأعمال)
  4. قائمة KeyStore مع KeyTool (Works)
  5. تحميل keystore برمجيا (فشل مع ioException: invalidKeystoreformat)

ما لا أحصل عليه هو ذلك في كل من الحفظ والتحميل ، أنا أستخدمه keystore.getInstance ("JKS"), ، لكن فشلها. أي اقتراحات مرحب بها!

إخراج وقت التشغيل:

Creating private keystore at 'private.keystore'.
Created keystore, now created signer cert
Created signer cert, saving cert
Reloading keystore:
Failed to load the keystore after creation: Invalid keystore format

مصدر حالة الاختبار:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import sun.security.x509.X500Name;

public class KeystoreCreator
{
 private String fPrivateKeyStore;
 private String fPrivateKeyStorePassword;
 private String fPrivateKeyStoreKeyPassword;
 private String fPublicKeyCipherPassword;
 private String fPrivateKeyAlias;

 /**
  * @param args
  * @throws Exception 
  */
 public static void main(String[] args) throws Exception
 {
  KeystoreCreator creator = new KeystoreCreator();

  creator.setPrivateKeyStore("private.keystore");
  creator.setPrivateKeyStorePassword("beer123");

  creator.setPrivateKeyAlias("myalias");
  creator.setPrivateKeyStoreKeyPassword("beer123");
  creator.setPublicKeyCipherPassword("beer123");

  creator.initKeyStores();
 }

 public KeystoreCreator()
 {  
 }

 public void setPrivateKeyStore(String name)
 {
  fPrivateKeyStore=name;
 }
 public void setPrivateKeyStorePassword(String pass)
 {
  fPrivateKeyStorePassword=pass;
 }
 public void setPrivateKeyStoreKeyPassword(String pass)
 {
  fPrivateKeyStoreKeyPassword=pass;
 }
 public void setPublicKeyCipherPassword(String pass)
 {
  fPublicKeyCipherPassword=pass;
 }
 public void setPrivateKeyAlias(String alias)
 {
  fPrivateKeyAlias=alias;
 }

    public void initKeyStores() throws Exception
    {
        OutputStream out = null;
        File f=new File(fPrivateKeyStore);
        if (f.exists())
        {
         f.delete();
         if (f.exists())
         {
          throw new IOException("Want to remove the keystore but can't, still reported as present after removal");
         }
        }
        try
        {
         System.out.println("Creating private keystore at '" + fPrivateKeyStore + "'.");
         out = new FileOutputStream(fPrivateKeyStore);
         KeyStore privateKeyStore = KeyStore.getInstance("JKS");
         privateKeyStore.load(null, fPrivateKeyStorePassword.toCharArray());

         System.out.println("Created keystore, now created signer cert");
         X500Name x500name=getCA();
         Certificate cert = createCertificate(fPrivateKeyAlias, fPrivateKeyStoreKeyPassword, x500name, privateKeyStore);

         System.out.println("Created signer cert, saving cert");
         privateKeyStore.store(out, fPublicKeyCipherPassword.toCharArray());
         out.flush();
         out.close();
         //try to load it.
         KeyStore reloadedKeyStore = KeyStore.getInstance("JKS");
         try
         {
          InputStream reloadedIs=getClass().getClassLoader().getResourceAsStream(fPrivateKeyStore);
          if (reloadedIs!=null)
          {
           System.out.println("Reloading keystore:");
           reloadedKeyStore.load(reloadedIs, fPrivateKeyStorePassword.toCharArray());
          }
         }
         catch (Exception e)
         {
          System.err.println("Failed to load the keystore after creation: "+e.getLocalizedMessage());
         }
        }
        catch (Exception e)
        {
         System.err.println("Failed to save the keystore: "+e.getLocalizedMessage());
        }
    }

    private X500Name getCA() throws IOException
    {
     return new sun.security.x509.X500Name("a","b", "c","d","e", "GB");
    }

    public Certificate createCertificate( String alias, String keyPassword,
            sun.security.x509.X500Name x500Name, KeyStore keyStore ) throws NoSuchAlgorithmException,
            InvalidKeyException, CertificateException, SignatureException, NoSuchProviderException,
            KeyStoreException {     
        sun.security.x509.CertAndKeyGen keypair = new sun.security.x509.CertAndKeyGen( "RSA", "MD5WithRSA" );
        keypair.generate( 1024 );
        PrivateKey privKey = keypair.getPrivateKey();
        X509Certificate[] chain = new X509Certificate[1];
        chain[0] = keypair.getSelfCertificate( x500Name, 7000 * 24 * 60 * 60 );
        keyStore.setKeyEntry( alias, privKey, keyPassword.toCharArray(), chain );

        Certificate cert = keyStore.getCertificate( alias );
        return cert;
    }
}
هل كانت مفيدة؟

المحلول

1) تقوم بإنشاء متجر المفاتيح الخاص في دليل العمل الحالي ، بواسطة الكتابة إلى ملف: new FileOutputStream(fPrivateKeyStore);

2) لاحقًا ، أنت اقرأ من مسار الفصل باستخدام getClass().getClassLoader().getResourceAsStream(fPrivateKeyStore);

أعتقد أنك تقرأ الملفات الخاطئة. وهناك بالفعل واحد آخر يحمل الاسم private.keystore من الاختبارات السابقة. للتحقق ، قد ترغب في طباعة مسار الملف المطلق لكلا الملفين ، على سبيل المثال new File(fPrivateKeyStore).getAbsolutePath() وقارنها بـ getClass().getClassLoader().getResource(fPrivateKeyStore).toFileURL();

نصائح أخرى

قد أفتقد شيئًا ما ، ولكن لماذا لا تعيد تحميل متجر المفاتيح الخاص فقط FileInputStream?

InputStream reloadedIs = new FileInputStream(fPrivateKeyStore);

(لست متأكدًا من أن هذا يحدد المشكلة ، لقد لاحظت ذلك فقط أثناء مسح الكود الخاص بك)

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