Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8047223

Add algorithm parameter to EncodedKeySpec class and its two subclasses

XMLWordPrintable

    • b33
    • Verified

        There is a gap in the security APIs for a use case in which a key is to be extracted from an EncodedKeySpec object. The missing piece is that there is no method that tells the algorithm of the key, which is necessary to create the KeyFactory.

        Consider the following example of the issue from the com.sun.org.apache.xml.internal.security.keys.content.DEREncodedKeyValue class. The getPublicKey() method attempts to generate a public key from an instance of X509EncodedKeySpec, a subclass of EncodedKeySpec. Because the public key algorithm is unknown to the X509EncodedKeySpec object, the method has no choice but to iterate over the supported key types, trying each until one works.

            public PublicKey getPublicKey() throws XMLSecurityException {
                byte[] encodedKey = getBytesFromTextChild();

                // Iterate over the supported key types until one produces a public key.
                for (String keyType : supportedKeyTypes) {
                    try {
                        KeyFactory keyFactory = KeyFactory.getInstance(keyType);
                        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey);
                        PublicKey publicKey = keyFactory.generatePublic(keySpec);
                        if (publicKey != null) {
                            return publicKey;
                        }
                    } catch (NoSuchAlgorithmException e) {
                        // Do nothing, try the next type
                    } catch (InvalidKeySpecException e) {
                        // Do nothing, try the next type
                    }
                }
                throw new XMLSecurityException("DEREncodedKeyValue.UnsupportedEncodedKey");
            }

        This problem is also encountered when extracting a private key from an PKCS8EncodedKeySpec. Again, the algorithm is unknown.

        EncryptedPrivateKeyInfo
            epki = new EncryptedPrivateKeyInfo(caPKCS8PrivateKey);
        PBEKeySpec pks = new PBEKeySpec(keyPasswd);
        SecretKeyFactory skf = SecretKeyFactory.getInstance(epki.getAlgName());
        SecretKey sk = skf.generateSecret(pks);
        PKCS8EncodedKeySpec ks = epki.getKeySpec(sk);
        // Don't know the algorithm needed for KeyFactory
        KeyFactory kf = KeyFactory.getInstance(???);
        PrivateKey pk = kf.generatePrivate(ks);

        EncryptedPrivateKeyInfo.getKeySpec() can use the internal DER encoding APIs to extract the private key algorithm from the encoded key, however, so adding this feature to PKCS8EncodedKeySpec will address this gap:

        KeyFactory kf = KeyFactory.getInstance(ks.getAlgorithm());

        Here is an initial draft of the new constructor and method:

            /**
             * Creates a new PKCS8EncodedKeySpec with the given encoded key and algorithm.
             *
             * @param encodedKey the key, which is assumed to be
             * encoded according to the PKCS #8 standard. The contents of
             * the array are copied to protect against subsequent modification.
             * @param algorithm the algorithm of the encoded private key
             * @exception NullPointerException if {@code encodedKey} or {@code algorithm}
             * is null.
             */
            public PKCS8EncodedKeySpec(byte[] encodedKey, String algorithm)

            /**
             * Returns the name of the algorithm of the encoded private key.
             *
             * @return the name of the algorithm, or null if not specified
             */
            public String getAlgorithm()

              juh Jason Uh (Inactive)
              mullan Sean Mullan
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Created:
                Updated:
                Resolved: