Search in sources :

Example 11 with EncryptedPrivateKeyInfo

use of sun.security.pkcs.EncryptedPrivateKeyInfo in project Bytecoder by mirkosertic.

the class KeyProtector method protect.

/*
     * Protects the given plaintext key, using the password provided at
     * construction time.
     */
public byte[] protect(Key key) throws KeyStoreException {
    int i;
    int numRounds;
    byte[] digest;
    // offset in xorKey where next digest will be stored
    int xorOffset;
    int encrKeyOffset = 0;
    if (key == null) {
        throw new IllegalArgumentException("plaintext key can't be null");
    }
    if (!"PKCS#8".equalsIgnoreCase(key.getFormat())) {
        throw new KeyStoreException("Cannot get key bytes, not PKCS#8 encoded");
    }
    byte[] plainKey = key.getEncoded();
    if (plainKey == null) {
        throw new KeyStoreException("Cannot get key bytes, encoding not supported");
    }
    // Determine the number of digest rounds
    numRounds = plainKey.length / DIGEST_LEN;
    if ((plainKey.length % DIGEST_LEN) != 0)
        numRounds++;
    // Create a random salt
    byte[] salt = new byte[SALT_LEN];
    SecureRandom random = new SecureRandom();
    random.nextBytes(salt);
    // Set up the byte array which will be XORed with "plainKey"
    byte[] xorKey = new byte[plainKey.length];
    // Compute the digests, and store them in "xorKey"
    for (i = 0, xorOffset = 0, digest = salt; i < numRounds; i++, xorOffset += DIGEST_LEN) {
        md.update(passwdBytes);
        md.update(digest);
        digest = md.digest();
        md.reset();
        // Copy the digest into "xorKey"
        if (i < numRounds - 1) {
            System.arraycopy(digest, 0, xorKey, xorOffset, digest.length);
        } else {
            System.arraycopy(digest, 0, xorKey, xorOffset, xorKey.length - xorOffset);
        }
    }
    // XOR "plainKey" with "xorKey", and store the result in "tmpKey"
    byte[] tmpKey = new byte[plainKey.length];
    for (i = 0; i < tmpKey.length; i++) {
        tmpKey[i] = (byte) (plainKey[i] ^ xorKey[i]);
    }
    // Store salt and "tmpKey" in "encrKey"
    byte[] encrKey = new byte[salt.length + tmpKey.length + DIGEST_LEN];
    System.arraycopy(salt, 0, encrKey, encrKeyOffset, salt.length);
    encrKeyOffset += salt.length;
    System.arraycopy(tmpKey, 0, encrKey, encrKeyOffset, tmpKey.length);
    encrKeyOffset += tmpKey.length;
    // Append digest(password, plainKey) as an integrity check to "encrKey"
    md.update(passwdBytes);
    Arrays.fill(passwdBytes, (byte) 0x00);
    passwdBytes = null;
    md.update(plainKey);
    digest = md.digest();
    md.reset();
    System.arraycopy(digest, 0, encrKey, encrKeyOffset, digest.length);
    // wrap the protected private key in a PKCS#8-style
    // EncryptedPrivateKeyInfo, and returns its encoding
    AlgorithmId encrAlg;
    try {
        encrAlg = new AlgorithmId(new ObjectIdentifier(KEY_PROTECTOR_OID));
        return new EncryptedPrivateKeyInfo(encrAlg, encrKey).getEncoded();
    } catch (IOException ioe) {
        throw new KeyStoreException(ioe.getMessage());
    }
}
Also used : AlgorithmId(sun.security.x509.AlgorithmId) SecureRandom(java.security.SecureRandom) EncryptedPrivateKeyInfo(sun.security.pkcs.EncryptedPrivateKeyInfo) KeyStoreException(java.security.KeyStoreException) IOException(java.io.IOException) ObjectIdentifier(sun.security.util.ObjectIdentifier)

Example 12 with EncryptedPrivateKeyInfo

use of sun.security.pkcs.EncryptedPrivateKeyInfo in project jdk8u_jdk by JetBrains.

the class PKCS12KeyStore method engineGetKey.

/**
     * Returns the key associated with the given alias, using the given
     * password to recover it.
     *
     * @param alias the alias name
     * @param password the password for recovering the key
     *
     * @return the requested key, or null if the given alias does not exist
     * or does not identify a <i>key entry</i>.
     *
     * @exception NoSuchAlgorithmException if the algorithm for recovering the
     * key cannot be found
     * @exception UnrecoverableKeyException if the key cannot be recovered
     * (e.g., the given password is wrong).
     */
public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException {
    Entry entry = entries.get(alias.toLowerCase(Locale.ENGLISH));
    Key key = null;
    if (entry == null || (!(entry instanceof KeyEntry))) {
        return null;
    }
    // get the encoded private key or secret key
    byte[] encrBytes = null;
    if (entry instanceof PrivateKeyEntry) {
        encrBytes = ((PrivateKeyEntry) entry).protectedPrivKey;
    } else if (entry instanceof SecretKeyEntry) {
        encrBytes = ((SecretKeyEntry) entry).protectedSecretKey;
    } else {
        throw new UnrecoverableKeyException("Error locating key");
    }
    byte[] encryptedKey;
    AlgorithmParameters algParams;
    ObjectIdentifier algOid;
    try {
        // get the encrypted private key
        EncryptedPrivateKeyInfo encrInfo = new EncryptedPrivateKeyInfo(encrBytes);
        encryptedKey = encrInfo.getEncryptedData();
        // parse Algorithm parameters
        DerValue val = new DerValue(encrInfo.getAlgorithm().encode());
        DerInputStream in = val.toDerInputStream();
        algOid = in.getOID();
        algParams = parseAlgParameters(algOid, in);
    } catch (IOException ioe) {
        UnrecoverableKeyException uke = new UnrecoverableKeyException("Private key not stored as " + "PKCS#8 EncryptedPrivateKeyInfo: " + ioe);
        uke.initCause(ioe);
        throw uke;
    }
    try {
        byte[] keyInfo;
        while (true) {
            try {
                // Use JCE
                SecretKey skey = getPBEKey(password);
                Cipher cipher = Cipher.getInstance(mapPBEParamsToAlgorithm(algOid, algParams));
                cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
                keyInfo = cipher.doFinal(encryptedKey);
                break;
            } catch (Exception e) {
                if (password.length == 0) {
                    // Retry using an empty password
                    // without a NULL terminator.
                    password = new char[1];
                    continue;
                }
                throw e;
            }
        }
        /*
             * Parse the key algorithm and then use a JCA key factory
             * to re-create the key.
             */
        DerValue val = new DerValue(keyInfo);
        DerInputStream in = val.toDerInputStream();
        int i = in.getInteger();
        DerValue[] value = in.getSequence(2);
        AlgorithmId algId = new AlgorithmId(value[0].getOID());
        String keyAlgo = algId.getName();
        // decode private key
        if (entry instanceof PrivateKeyEntry) {
            KeyFactory kfac = KeyFactory.getInstance(keyAlgo);
            PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(keyInfo);
            key = kfac.generatePrivate(kspec);
            if (debug != null) {
                debug.println("Retrieved a protected private key (" + key.getClass().getName() + ") at alias '" + alias + "'");
            }
        // decode secret key
        } else {
            byte[] keyBytes = in.getOctetString();
            SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, keyAlgo);
            // Special handling required for PBE: needs a PBEKeySpec
            if (keyAlgo.startsWith("PBE")) {
                SecretKeyFactory sKeyFactory = SecretKeyFactory.getInstance(keyAlgo);
                KeySpec pbeKeySpec = sKeyFactory.getKeySpec(secretKeySpec, PBEKeySpec.class);
                key = sKeyFactory.generateSecret(pbeKeySpec);
            } else {
                key = secretKeySpec;
            }
            if (debug != null) {
                debug.println("Retrieved a protected secret key (" + key.getClass().getName() + ") at alias '" + alias + "'");
            }
        }
    } catch (Exception e) {
        UnrecoverableKeyException uke = new UnrecoverableKeyException("Get Key failed: " + e.getMessage());
        uke.initCause(e);
        throw uke;
    }
    return key;
}
Also used : SecretKeySpec(javax.crypto.spec.SecretKeySpec) KeySpec(java.security.spec.KeySpec) PBEKeySpec(javax.crypto.spec.PBEKeySpec) PKCS8EncodedKeySpec(java.security.spec.PKCS8EncodedKeySpec) UnrecoverableKeyException(java.security.UnrecoverableKeyException) SecretKeySpec(javax.crypto.spec.SecretKeySpec) DerValue(sun.security.util.DerValue) DerInputStream(sun.security.util.DerInputStream) SecretKeyFactory(javax.crypto.SecretKeyFactory) SecretKeyFactory(javax.crypto.SecretKeyFactory) KeyFactory(java.security.KeyFactory) ObjectIdentifier(sun.security.util.ObjectIdentifier) KeyStoreException(java.security.KeyStoreException) UnrecoverableKeyException(java.security.UnrecoverableKeyException) UnrecoverableEntryException(java.security.UnrecoverableEntryException) DestroyFailedException(javax.security.auth.DestroyFailedException) CertificateException(java.security.cert.CertificateException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) SecretKey(javax.crypto.SecretKey) AlgorithmId(sun.security.x509.AlgorithmId) PKCS8EncodedKeySpec(java.security.spec.PKCS8EncodedKeySpec) EncryptedPrivateKeyInfo(sun.security.pkcs.EncryptedPrivateKeyInfo) Cipher(javax.crypto.Cipher) Key(java.security.Key) PrivateKey(java.security.PrivateKey) SecretKey(javax.crypto.SecretKey) AlgorithmParameters(java.security.AlgorithmParameters)

Example 13 with EncryptedPrivateKeyInfo

use of sun.security.pkcs.EncryptedPrivateKeyInfo in project jdk8u_jdk by JetBrains.

the class PKCS12SameKeyId method main.

public static void main(String[] args) throws Exception {
    // Prepare a JKS keystore with many entries
    new File(JKSFILE).delete();
    for (int i = 0; i < SIZE; i++) {
        System.err.print(".");
        String cmd = "-keystore " + JKSFILE + " -storepass changeit -keypass changeit -keyalg rsa " + "-genkeypair -alias p" + i + " -dname CN=" + i;
        sun.security.tools.keytool.Main.main(cmd.split(" "));
    }
    // Prepare EncryptedPrivateKeyInfo parameters, copied from various
    // places in PKCS12KeyStore.java
    AlgorithmParameters algParams = AlgorithmParameters.getInstance("PBEWithSHA1AndDESede");
    algParams.init(new PBEParameterSpec("12345678".getBytes(), 1024));
    AlgorithmId algid = new AlgorithmId(new ObjectIdentifier("1.2.840.113549.1.12.1.3"), algParams);
    PBEKeySpec keySpec = new PBEKeySpec(PASSWORD);
    SecretKeyFactory skFac = SecretKeyFactory.getInstance("PBE");
    SecretKey skey = skFac.generateSecret(keySpec);
    Cipher cipher = Cipher.getInstance("PBEWithSHA1AndDESede");
    cipher.init(Cipher.ENCRYPT_MODE, skey, algParams);
    // Pre-calculated keys and certs and aliases
    byte[][] keys = new byte[SIZE][];
    Certificate[][] certChains = new Certificate[SIZE][];
    String[] aliases = new String[SIZE];
    // Reads from JKS keystore and pre-calculate
    KeyStore ks = KeyStore.getInstance("jks");
    try (FileInputStream fis = new FileInputStream(JKSFILE)) {
        ks.load(fis, PASSWORD);
    }
    for (int i = 0; i < SIZE; i++) {
        aliases[i] = "p" + i;
        byte[] enckey = cipher.doFinal(ks.getKey(aliases[i], PASSWORD).getEncoded());
        keys[i] = new EncryptedPrivateKeyInfo(algid, enckey).getEncoded();
        certChains[i] = ks.getCertificateChain(aliases[i]);
    }
    // Write into PKCS12 keystore. Use this overloaded version of
    // setKeyEntry() to be as fast as possible, so that they would
    // have same localKeyId.
    KeyStore p12 = KeyStore.getInstance("pkcs12");
    p12.load(null, PASSWORD);
    for (int i = 0; i < SIZE; i++) {
        p12.setKeyEntry(aliases[i], keys[i], certChains[i]);
    }
    try (FileOutputStream fos = new FileOutputStream(P12FILE)) {
        p12.store(fos, PASSWORD);
    }
    // Check private keys still match certs
    p12 = KeyStore.getInstance("pkcs12");
    try (FileInputStream fis = new FileInputStream(P12FILE)) {
        p12.load(fis, PASSWORD);
    }
    for (int i = 0; i < SIZE; i++) {
        String a = "p" + i;
        X509Certificate x = (X509Certificate) p12.getCertificate(a);
        X500Name name = (X500Name) x.getSubjectDN();
        if (!name.getCommonName().equals("" + i)) {
            throw new Exception(a + "'s cert is " + name);
        }
    }
}
Also used : PBEKeySpec(javax.crypto.spec.PBEKeySpec) X500Name(sun.security.x509.X500Name) KeyStore(java.security.KeyStore) FileInputStream(java.io.FileInputStream) X509Certificate(java.security.cert.X509Certificate) SecretKey(javax.crypto.SecretKey) AlgorithmId(sun.security.x509.AlgorithmId) FileOutputStream(java.io.FileOutputStream) EncryptedPrivateKeyInfo(sun.security.pkcs.EncryptedPrivateKeyInfo) Cipher(javax.crypto.Cipher) File(java.io.File) SecretKeyFactory(javax.crypto.SecretKeyFactory) PBEParameterSpec(javax.crypto.spec.PBEParameterSpec) AlgorithmParameters(java.security.AlgorithmParameters) ObjectIdentifier(sun.security.util.ObjectIdentifier) X509Certificate(java.security.cert.X509Certificate) Certificate(java.security.cert.Certificate)

Example 14 with EncryptedPrivateKeyInfo

use of sun.security.pkcs.EncryptedPrivateKeyInfo in project Bytecoder by mirkosertic.

the class PKCS12KeyStore method encryptPrivateKey.

/*
     * Encrypt private key using Password-based encryption (PBE)
     * as defined in PKCS#5.
     *
     * NOTE: By default, pbeWithSHAAnd3-KeyTripleDES-CBC algorithmID is
     *       used to derive the key and IV.
     *
     * @return encrypted private key encoded as EncryptedPrivateKeyInfo
     */
private byte[] encryptPrivateKey(byte[] data, KeyStore.PasswordProtection passwordProtection) throws IOException, NoSuchAlgorithmException, UnrecoverableKeyException {
    byte[] key = null;
    try {
        String algorithm;
        AlgorithmParameters algParams;
        AlgorithmId algid;
        // Initialize PBE algorithm and parameters
        algorithm = passwordProtection.getProtectionAlgorithm();
        if (algorithm != null) {
            AlgorithmParameterSpec algParamSpec = passwordProtection.getProtectionParameters();
            if (algParamSpec != null) {
                algParams = AlgorithmParameters.getInstance(algorithm);
                algParams.init(algParamSpec);
            } else {
                algParams = getAlgorithmParameters(algorithm);
            }
        } else {
            // Check default key protection algorithm for PKCS12 keystores
            algorithm = AccessController.doPrivileged(new PrivilegedAction<String>() {

                public String run() {
                    String prop = Security.getProperty(KEY_PROTECTION_ALGORITHM[0]);
                    if (prop == null) {
                        prop = Security.getProperty(KEY_PROTECTION_ALGORITHM[1]);
                    }
                    return prop;
                }
            });
            if (algorithm == null || algorithm.isEmpty()) {
                algorithm = "PBEWithSHA1AndDESede";
            }
            algParams = getAlgorithmParameters(algorithm);
        }
        ObjectIdentifier pbeOID = mapPBEAlgorithmToOID(algorithm);
        if (pbeOID == null) {
            throw new IOException("PBE algorithm '" + algorithm + " 'is not supported for key entry protection");
        }
        // Use JCE
        SecretKey skey = getPBEKey(passwordProtection.getPassword());
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, skey, algParams);
        byte[] encryptedKey = cipher.doFinal(data);
        algid = new AlgorithmId(pbeOID, cipher.getParameters());
        if (debug != null) {
            debug.println("  (Cipher algorithm: " + cipher.getAlgorithm() + ")");
        }
        // wrap encrypted private key in EncryptedPrivateKeyInfo
        // as defined in PKCS#8
        EncryptedPrivateKeyInfo encrInfo = new EncryptedPrivateKeyInfo(algid, encryptedKey);
        key = encrInfo.getEncoded();
    } catch (Exception e) {
        UnrecoverableKeyException uke = new UnrecoverableKeyException("Encrypt Private Key failed: " + e.getMessage());
        uke.initCause(e);
        throw uke;
    }
    return key;
}
Also used : KeyStoreException(java.security.KeyStoreException) InvalidAlgorithmParameterException(java.security.InvalidAlgorithmParameterException) UnrecoverableKeyException(java.security.UnrecoverableKeyException) UnrecoverableEntryException(java.security.UnrecoverableEntryException) DestroyFailedException(javax.security.auth.DestroyFailedException) CertificateException(java.security.cert.CertificateException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) InvalidKeyException(java.security.InvalidKeyException) SecretKey(javax.crypto.SecretKey) UnrecoverableKeyException(java.security.UnrecoverableKeyException) AlgorithmId(sun.security.x509.AlgorithmId) PrivilegedAction(java.security.PrivilegedAction) EncryptedPrivateKeyInfo(sun.security.pkcs.EncryptedPrivateKeyInfo) Cipher(javax.crypto.Cipher) AlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec) AlgorithmParameters(java.security.AlgorithmParameters) ObjectIdentifier(sun.security.util.ObjectIdentifier)

Example 15 with EncryptedPrivateKeyInfo

use of sun.security.pkcs.EncryptedPrivateKeyInfo in project Bytecoder by mirkosertic.

the class PKCS12KeyStore method createSafeContent.

/*
     * Create SafeContent Data content type.
     * Includes encrypted secret key in a SafeBag of type SecretBag.
     * Includes encrypted private key in a SafeBag of type PKCS8ShroudedKeyBag.
     * Each PKCS8ShroudedKeyBag includes pkcs12 attributes
     * (see comments in getBagAttributes)
     */
private byte[] createSafeContent() throws CertificateException, IOException {
    DerOutputStream out = new DerOutputStream();
    for (Enumeration<String> e = engineAliases(); e.hasMoreElements(); ) {
        String alias = e.nextElement();
        Entry entry = entries.get(alias);
        if (entry == null || (!(entry instanceof KeyEntry))) {
            continue;
        }
        DerOutputStream safeBag = new DerOutputStream();
        KeyEntry keyEntry = (KeyEntry) entry;
        // DER encode the private key
        if (keyEntry instanceof PrivateKeyEntry) {
            // Create SafeBag of type pkcs8ShroudedKeyBag
            safeBag.putOID(PKCS8ShroudedKeyBag_OID);
            // get the encrypted private key
            byte[] encrBytes = ((PrivateKeyEntry) keyEntry).protectedPrivKey;
            EncryptedPrivateKeyInfo encrInfo = null;
            try {
                encrInfo = new EncryptedPrivateKeyInfo(encrBytes);
            } catch (IOException ioe) {
                throw new IOException("Private key not stored as " + "PKCS#8 EncryptedPrivateKeyInfo" + ioe.getMessage());
            }
            // Wrap the EncryptedPrivateKeyInfo in a context-specific tag.
            DerOutputStream bagValue = new DerOutputStream();
            bagValue.write(encrInfo.getEncoded());
            safeBag.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0), bagValue);
        // DER encode the secret key
        } else if (keyEntry instanceof SecretKeyEntry) {
            // Create SafeBag of type SecretBag
            safeBag.putOID(SecretBag_OID);
            // Create a SecretBag
            DerOutputStream secretBag = new DerOutputStream();
            secretBag.putOID(PKCS8ShroudedKeyBag_OID);
            // Write secret key in a context-specific tag
            DerOutputStream secretKeyValue = new DerOutputStream();
            secretKeyValue.putOctetString(((SecretKeyEntry) keyEntry).protectedSecretKey);
            secretBag.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0), secretKeyValue);
            // Wrap SecretBag in a Sequence
            DerOutputStream secretBagSeq = new DerOutputStream();
            secretBagSeq.write(DerValue.tag_Sequence, secretBag);
            byte[] secretBagValue = secretBagSeq.toByteArray();
            // Wrap the secret bag in a context-specific tag.
            DerOutputStream bagValue = new DerOutputStream();
            bagValue.write(secretBagValue);
            // Write SafeBag value
            safeBag.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0), bagValue);
        } else {
            // skip this entry
            continue;
        }
        // write SafeBag Attributes
        byte[] bagAttrs = getBagAttributes(alias, entry.keyId, entry.attributes);
        safeBag.write(bagAttrs);
        // wrap as Sequence
        out.write(DerValue.tag_Sequence, safeBag);
    }
    // wrap as Sequence
    DerOutputStream safeBagValue = new DerOutputStream();
    safeBagValue.write(DerValue.tag_Sequence, out);
    return safeBagValue.toByteArray();
}
Also used : DerOutputStream(sun.security.util.DerOutputStream) EncryptedPrivateKeyInfo(sun.security.pkcs.EncryptedPrivateKeyInfo)

Aggregations

EncryptedPrivateKeyInfo (sun.security.pkcs.EncryptedPrivateKeyInfo)16 KeyStoreException (java.security.KeyStoreException)8 ObjectIdentifier (sun.security.util.ObjectIdentifier)7 AlgorithmId (sun.security.x509.AlgorithmId)7 AlgorithmParameters (java.security.AlgorithmParameters)5 Cipher (javax.crypto.Cipher)5 SecretKey (javax.crypto.SecretKey)5 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)4 UnrecoverableEntryException (java.security.UnrecoverableEntryException)4 UnrecoverableKeyException (java.security.UnrecoverableKeyException)4 CertificateException (java.security.cert.CertificateException)4 DestroyFailedException (javax.security.auth.DestroyFailedException)4 SecretKeyFactory (javax.crypto.SecretKeyFactory)3 PBEKeySpec (javax.crypto.spec.PBEKeySpec)3 IOException (java.io.IOException)2 InvalidAlgorithmParameterException (java.security.InvalidAlgorithmParameterException)2 InvalidKeyException (java.security.InvalidKeyException)2 Key (java.security.Key)2 KeyFactory (java.security.KeyFactory)2 PrivateKey (java.security.PrivateKey)2