9
votes

Pourquoi est-ce que je reçois l'erreur "Impossible de stocker des non-privilèges" lors de la création d'une prise SSL en Java?

Je travaille sur une ancienne IBM iSeries (IBM-i, i5OS, AS / 400, etc.), avec une machine virtuelle Java Java 5 (Classic, pas JTI J9) sur la version O / S V5R3M0.

Voici la scénario en un mot: p>

  1. J'ai créé un magasin de clé de JKS type en utilisant Portecle 1.7 (Note: J'ai essayé convertir ma clé -Store à JCEKS mais qui a été rejeté comme un format non pris en charge, il semble donc que JKS est la seule option avec la machine iSeries (au moins la version que je suis sur). li>
  2. J'ai ensuite créé une paire de clés et la RSE et envoyé la RSE à Thawte à signer. Li>
  3. J'ai importé le certificat signé de Thawte avec succès en utilisant le PKCS # 7 format à importer la totalité de la chaîne de certificats, qui comprenait mon certificat, l'intermédiaire et la racine Thawte du serveur Thawte. Li> Ol>

    Tout cela a fonctionné comme prévu. P>

    Cependant, quand je courais la machine virtuelle Java, correctement configuré pour pointer vers la boutique et lui fournir son mot de passe (que je l'ai fait dans le passé avec l'auto certificats signé: créés dans Portecle pour les tests), et essayez de démarrer mon serveur web sur 443, je reçois l'exception de sécurité suivant: p>

    java.security.KeyStoreException: Cannot store non-PrivateKeys
    


0 commentaires

3 Réponses :


43
votes

Le « Impossible de stocker non-PrivateKeys » message d'erreur indique généralement que vous essayez d'utiliser des clés symétriques secrètes avec un JKS de type keystore. Le JKS de type ne supporte que les clés asymétriques (public / privé). Vous devez créer un nouveau fichier de clés de type JCEKS pour soutenir les clés secrètes.


1 commentaires

Merci oui. Le mystère était pourquoi créer une prise SSL essayait d'ajouter toutes les clés au magasin de clés. Il s'avère que j'essayais d'ajouter une clé nulle à un magasin de clés - Détail est dans ma réponse de soi à cette question.



6
votes

Comme il s'avère, c'était un problème subtil, et cela vaut la peine de donner la réponse ici au cas où quelqu'un d'autre ait quelque chose de similaire.

La réponse TLDR est que je n'ai pas vérifié que ma clé et ma certificat n'étaient pas nulles et En conséquence, a tenté d'ajouter une clé nulle et un certificat à un magasin de clés. La réponse la plus longue suit. P>

La manière dont nous avons notre serveur Web configuré pour utiliser SSL, spécifiquement pour prendre en charge la configuration typique de notre utilisateur où l'adresse IP est utilisée pour configurer l'adresse d'écoute du site Web plutôt qu'un nom DNS. , est-ce qu'il localise le certificat dans le magasin de clés maître à l'aide de l'alias et crée un magasin de clé-clés éphémère contenant uniquement le certificat de ce site Web, en utilisant ce magasin de clé pour configurer un contexte SSL et une prise SSL Factory, comme Donc: P>

// CREATE EPHEMERAL KEYSTORE FOR THIS SOCKET USING THE DESIRED CERTIFICATE
try {
    final char[]      BLANK_PWD=new char[0];
    SSLContext        ctx=SSLContext.getInstance("TLS");
    KeyManagerFactory kmf=KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    Key               ctfkey=mstkst.getKey(svrctfals,BLANK_PWD);
    Certificate[]     ctfchn=mstkst.getCertificateChain(svrctfals);
    KeyStore          sktkst;

    if(ctfkey==null) {
        throw new IOException("Cannot create server socket factory: No key found for alias '"+svrctfals+"'");
        }
    if(ctfchn==null || ctfchn.length==0) {
        throw new IOException("Cannot create server socket factory: No certificate found for alias '"+svrctfals+"'");
        }

    sktkst=KeyStore.getInstance("jks");
    sktkst.load(null,BLANK_PWD);
    sktkst.setKeyEntry(svrctfals,ctfkey,BLANK_PWD,ctfchn);
    kmf.init(sktkst,BLANK_PWD);
    ctx.init(kmf.getKeyManagers(),null,null);
    ssf=ctx.getServerSocketFactory();
    }
catch(java.security.GeneralSecurityException thr) {
    throw new IOException("Cannot create server socket factory using ephemeral keystore ("+thr+")",thr);
    }


0 commentaires

3
votes

Au lieu d'utiliser un keystore éphémère, vous pouvez tout gérer dans un seul SSLContext .

Vous auriez besoin de votre initialiser SSLContext en utilisant une commande X509KeyManager au lieu d'utiliser celle donnée par la valeur par défaut KeyManagerFactory . Dans ce X509KeyManager , chooseServerAlias ​​(String keyType, les émetteurs, châsse principaux []) doit retourner un alias différents en fonction de l'adresse locale obtenue à partir de la douille.

De cette façon, vous ne seriez pas à vous soucier de copier la clé privée d'un keystore à l'autre, et cela même pour les types de travaux keystore à partir de laquelle vous ne pouvez pas extraire (et donc copier) mais seulement utiliser la clé privée , par exemple PKCS # 11.


1 commentaires

Merci; Je vais regarder dans ça.