Package com.adito.security.pki

Source Code of com.adito.security.pki.SshtoolsPrivateKeyFormat

        /*
*  Adito
*
*  Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU General Public License
*  as published by the Free Software Foundation; either version 2 of
*  the License, or (at your option) any later version.
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public
*  License along with this program; if not, write to the Free Software
*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
     
package com.adito.security.pki;

import java.io.IOException;
import java.security.Key;
import java.security.spec.KeySpec;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;

import com.maverick.crypto.digests.Hash;
import com.maverick.util.ByteArrayReader;
import com.maverick.util.ByteArrayWriter;


/**
*
*
* @author $author$
*/
public class SshtoolsPrivateKeyFormat extends Base64EncodedFileFormat
    implements SshPrivateKeyFormat {
    private static String BEGIN = "---- BEGIN SSHTOOLS ENCRYPTED PRIVATE KEY ----";
    private static String END = "---- END SSHTOOLS ENCRYPTED PRIVATE KEY ----";
    private int cookie = 0x52f37abe;

    /**
     * Creates a new SshtoolsPrivateKeyFormat object.
     *
     * @param subject
     * @param comment
     */
    public SshtoolsPrivateKeyFormat(String subject, String comment) {
        super(BEGIN, END);
        setHeaderValue("Subject", subject);
        setHeaderValue("Comment", comment);
    }

    /**
     * Creates a new SshtoolsPrivateKeyFormat object.
     */
    public SshtoolsPrivateKeyFormat() {
        super(BEGIN, END);
    }

    /**
     *
     *
     * @return
     */
    public String getFormatType() {
        return "SSHTools-PrivateKey-" + super.getFormatType();
    }

    /**
     *
     *
     * @param formattedKey
     *
     * @return
     */
    public boolean isPassphraseProtected(byte[] formattedKey) {
        try {
            ByteArrayReader bar = new ByteArrayReader(getKeyBlob(formattedKey));
            String type = bar.readString();

            if (type.equals("none")) {
                return false;
            }

            if (type.equalsIgnoreCase("3des-cbc")) {
                return true;
            }
        } catch (IOException ioe) {
        } catch(InvalidKeyException ex) {
        }

        return false;
    }

    /**
     *
     *
     * @param formattedKey
     * @param passphrase
     *
     * @return
     *
     * @throws InvalidKeyException
     */
    public byte[] decryptKeyblob(byte[] formattedKey, String passphrase)
        throws InvalidKeyException {
        try {
            byte[] keyblob = getKeyBlob(formattedKey);
            ByteArrayReader bar = new ByteArrayReader(keyblob);
            String type = bar.readString();

            if (type.equalsIgnoreCase("3des-cbc")) {
                // Decrypt the key
                byte[] keydata = makePassphraseKey(passphrase);
                byte[] iv = new byte[8];

                if (type.equals("3DES-CBC")) {
                    bar.read(iv);
                }

                keyblob = bar.readBinaryString();

                Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
                KeySpec keyspec = new DESedeKeySpec(keydata);
                Key key = SecretKeyFactory.getInstance("DESede").generateSecret(keyspec);
                cipher.init(Cipher.DECRYPT_MODE, key,
                    new IvParameterSpec(iv, 0, cipher.getBlockSize()));

                ByteArrayReader data = new ByteArrayReader(cipher.doFinal(
                            keyblob));

                if (data.readInt() == cookie) {
                    keyblob = data.readBinaryString();
                } else {
                    throw new InvalidKeyException(
                        "The host key is invalid, check the passphrase supplied");
                }
            } else {
                keyblob = bar.readBinaryString();
            }

            return keyblob;
        } catch (Exception aoe) {
            throw new InvalidKeyException("Failed to read host key");
        }
    }

    /**
     *
     *
     * @param keyblob
     * @param passphrase
     *
     * @return
     */
    public byte[] encryptKeyblob(byte[] keyblob, String passphrase) {
        try {
            ByteArrayWriter baw = new ByteArrayWriter();
            String type = "none";

            if (passphrase != null) {
                if (!passphrase.trim().equals("")) {
                    // Encrypt the data
                    type = "3DES-CBC";

                    // Decrypt the key
                    byte[] keydata = makePassphraseKey(passphrase);
                    byte[] iv = new byte[8];
                    Utils.getRND().nextBytes(iv);

                    Cipher cipher = Cipher.getInstance(
                            "DESede/CBC/PKCS5Padding");
                    KeySpec keyspec = new DESedeKeySpec(keydata);
                    Key key = SecretKeyFactory.getInstance("DESede")
                                              .generateSecret(keyspec);
                    cipher.init(Cipher.ENCRYPT_MODE, key,
                        new IvParameterSpec(iv, 0, cipher.getBlockSize()));

                    ByteArrayWriter data = new ByteArrayWriter();
                    baw.writeString(type);
                    baw.write(iv);
                    data.writeInt(cookie);
                    data.writeBinaryString(keyblob);

                    // Encrypt and write
                    baw.writeBinaryString(cipher.doFinal(data.toByteArray()));

                    return formatKey(baw.toByteArray());
                }
            }

            // Write the type of encryption
            baw.writeString(type);

            // Write the key blob
            baw.writeBinaryString(keyblob);

            // Now set the keyblob to our new encrpyted (or not) blob
            return formatKey(baw.toByteArray());
        } catch (Exception ioe) {
            return null;
        }
    }

    /**
     *
     *
     * @param algorithm
     *
     * @return
     */
    public boolean supportsAlgorithm(String algorithm) {
        return true;
    }

    private byte[] makePassphraseKey(String passphrase) {
            // Generate the key using the passphrase
            Hash md5 = new Hash("MD5");
            md5.putBytes(passphrase.getBytes());

            byte[] key1 = md5.doFinal();
            md5.reset();
            md5.putBytes(passphrase.getBytes());
            md5.putBytes(key1);

            byte[] key2 = md5.doFinal();
            byte[] key = new byte[32];
            System.arraycopy(key1, 0, key, 0, 16);
            System.arraycopy(key2, 0, key, 16, 16);

            return key;
    }
}
TOP

Related Classes of com.adito.security.pki.SshtoolsPrivateKeyFormat

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.