Search in sources :

Example 56 with CryptoException

use of org.kse.crypto.CryptoException in project keystore-explorer by kaikramer.

the class MsPvkUtil method loadEncrypted.

/**
 * Load an encrypted PVK private key from the specified stream.
 *
 * @param is
 *            Stream load the encrypted private key from
 * @param password
 *            Password to decrypt
 * @return The private key
 * @throws PrivateKeyUnencryptedException
 *             If private key is unencrypted
 * @throws CryptoException
 *             Problem encountered while loading the private key
 * @throws IOException
 *             An I/O error occurred
 */
public static PrivateKey loadEncrypted(InputStream is, Password password) throws IOException, CryptoException {
    try {
        byte[] pvk = ReadUtil.readFully(is);
        // Wrap in a byte buffer set up to read little endian
        ByteBuffer bb = ByteBuffer.wrap(pvk);
        bb.order(ByteOrder.LITTLE_ENDIAN);
        // Read and validate the reserved, magic number and key type fields - only returns the latter
        long keyType = readReservedMagicKeyType(bb);
        // Read and validate encrypted field
        long encrypted = UnsignedUtil.getInt(bb);
        if (encrypted != PVK_ENCRYPTED) {
            throw new PrivateKeyUnencryptedException(MessageFormat.format(res.getString("MsPvkIsUnencrypted.exception.message"), Long.toHexString(encrypted), Long.toHexString(PVK_ENCRYPTED)));
        }
        // Read and validate salt length field
        long saltLength = UnsignedUtil.getInt(bb);
        if (saltLength != ENCRYPTED_SALT_LENGTH) {
            // Specific length for encrypted PVK
            throw new CryptoException(MessageFormat.format(res.getString("InvalidMsPvkSaltLengthField.exception.message"), Long.toHexString(saltLength), Long.toHexString(ENCRYPTED_SALT_LENGTH)));
        }
        // Read key length
        long keyLength = UnsignedUtil.getInt(bb);
        // Create decryption keys
        // Strong version
        byte[] strongKey = new byte[16];
        // Weak version
        byte[] weakKey = new byte[16];
        // Read Salt
        byte[] salt = new byte[(int) saltLength];
        bb.get(salt);
        // Concatenate salt and password and derive key using SHA-1
        MessageDigest messagedigest = MessageDigest.getInstance("SHA1");
        byte[] passwordBytes = new String(password.toCharArray()).getBytes();
        byte[] saltAndPassword = new byte[salt.length + passwordBytes.length];
        System.arraycopy(salt, 0, saltAndPassword, 0, salt.length);
        System.arraycopy(passwordBytes, 0, saltAndPassword, salt.length, passwordBytes.length);
        byte[] key = messagedigest.digest(saltAndPassword);
        // Create strong key - first 16 bytes of key
        System.arraycopy(key, 0, strongKey, 0, 16);
        // Create weak key - first 5 bytes of key followed by 11 zero bytes
        System.arraycopy(key, 0, weakKey, 0, 5);
        for (int i = 5; i < 16; i++) {
            weakKey[i] = 0;
        }
        // Read private key blob header
        readPrivateKeyBlobHeader(bb, keyType);
        // Read all remaining bytes - the encrypted key
        byte[] encryptedPrivateKeyBlob = new byte[bb.remaining()];
        bb.get(encryptedPrivateKeyBlob);
        // Validate key length - should be length of encrypted key blob plus blob header
        if (keyLength != (encryptedPrivateKeyBlob.length + BLOB_HEADER_LENGTH)) {
            throw new CryptoException(MessageFormat.format(res.getString("InvalidMsPvkKeyLengthField.exception.message"), Long.toHexString(keyLength), Long.toHexString(encryptedPrivateKeyBlob.length + BLOB_HEADER_LENGTH)));
        }
        // Decrypt key using RC4 with strong key
        byte[] decryptedPrivateKeyBlob = decryptPrivateKeyBlob(encryptedPrivateKeyBlob, strongKey);
        // Test for success
        if (decryptedPrivateKeyBlob == null) {
            // Failed - now try weak key
            decryptedPrivateKeyBlob = decryptPrivateKeyBlob(encryptedPrivateKeyBlob, weakKey);
            if (decryptedPrivateKeyBlob == null) {
                // Failed - could not decrypt - password is most likely incorrect
                throw new CryptoException(res.getString("NoDecryptMsPvkCheckPassword.exception.message"));
            }
        }
        return blobToPrivateKey(decryptedPrivateKeyBlob);
    } catch (GeneralSecurityException ex) {
        throw new CryptoException(res.getString("NoLoadMsPvk.exception.message"), ex);
    }
}
Also used : GeneralSecurityException(java.security.GeneralSecurityException) CryptoException(org.kse.crypto.CryptoException) MessageDigest(java.security.MessageDigest) ByteBuffer(java.nio.ByteBuffer)

Example 57 with CryptoException

use of org.kse.crypto.CryptoException in project keystore-explorer by kaikramer.

the class MsPvkUtil method getEncryptedInternal.

private static byte[] getEncryptedInternal(PrivateKey privateKey, int keyType, Password password, boolean strong) throws CryptoException {
    try {
        // Write PVK to a byte buffer set up to write little endian
        ByteBuffer bb = ByteBuffer.wrap(new byte[PVK_BUFFER_LENGTH]);
        bb.order(ByteOrder.LITTLE_ENDIAN);
        // Write magic number, reserved and and key type fields
        writeReservedMagicKeyType(bb, keyType);
        // Get password as bytes
        byte[] passwordBytes = new String(password.toCharArray()).getBytes();
        // Generate salt for encryption
        byte[] salt = generate16ByteSalt();
        // Concatenate the salt and password
        byte[] saltAndPassword = new byte[salt.length + passwordBytes.length];
        System.arraycopy(salt, 0, saltAndPassword, 0, salt.length);
        System.arraycopy(passwordBytes, 0, saltAndPassword, salt.length, passwordBytes.length);
        // Digest the salt and password to create the encryption key
        MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
        byte[] key = messageDigest.digest(saltAndPassword);
        // Get private key blob
        byte[] privateKeyBlob = null;
        if (privateKey instanceof RSAPrivateCrtKey) {
            privateKeyBlob = rsaPrivateKeyToBlob((RSAPrivateCrtKey) privateKey);
        } else {
            privateKeyBlob = dsaPrivateKeyToBlob((DSAPrivateKey) privateKey);
        }
        // Encrypt private key blob
        byte[] encryptedPrivateKeyBlob = null;
        if (strong) {
            // Strong version uses all 16 bytes of the key
            byte[] strongKey = new byte[16];
            System.arraycopy(key, 0, strongKey, 0, strongKey.length);
            encryptedPrivateKeyBlob = encryptPrivateKeyBlob(privateKeyBlob, strongKey);
        } else {
            // The weak version uses only 5 bytes of the key followed by 11 zero bytes
            byte[] weakKey = new byte[16];
            System.arraycopy(key, 0, weakKey, 0, 5);
            for (int i = 5; i < weakKey.length; i++) {
                weakKey[i] = 0;
            }
            encryptedPrivateKeyBlob = encryptPrivateKeyBlob(privateKeyBlob, weakKey);
        }
        // Write type field - encrypted
        UnsignedUtil.putInt(bb, PVK_ENCRYPTED);
        // Write salt length field
        UnsignedUtil.putInt(bb, salt.length);
        // Write key length field - length of the blob plus length blob header
        int keyLength = encryptedPrivateKeyBlob.length + BLOB_HEADER_LENGTH;
        UnsignedUtil.putInt(bb, keyLength);
        // Write salt
        bb.put(salt);
        // Write private key blob header
        writePrivateKeyBlobHeader(bb, keyType, privateKey);
        // Write blob
        bb.put(encryptedPrivateKeyBlob);
        byte[] encryptedPvk = getBufferBytes(bb);
        return encryptedPvk;
    } catch (IOException ex) {
        throw new CryptoException(res.getString("NoGetMsPvk.exception.message"), ex);
    } catch (NoSuchAlgorithmException ex) {
        throw new CryptoException(res.getString("NoGetMsPvk.exception.message"), ex);
    }
}
Also used : RSAPrivateCrtKey(java.security.interfaces.RSAPrivateCrtKey) DSAPrivateKey(java.security.interfaces.DSAPrivateKey) IOException(java.io.IOException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) MessageDigest(java.security.MessageDigest) CryptoException(org.kse.crypto.CryptoException) ByteBuffer(java.nio.ByteBuffer)

Example 58 with CryptoException

use of org.kse.crypto.CryptoException in project keystore-explorer by kaikramer.

the class MsPvkUtil method rsaPrivateKeyToBlob.

private static byte[] rsaPrivateKeyToBlob(RSAPrivateCrtKey rsaPrivCrtKey) throws CryptoException {
    try {
        // 2316 sufficient for a 4096 bit RSA key
        ByteBuffer bb = ByteBuffer.wrap(new byte[4096]);
        bb.order(ByteOrder.LITTLE_ENDIAN);
        // Write out the blob fields
        // rsapubkey.magic
        UnsignedUtil.putInt(bb, RSA_PRIV_MAGIC);
        BigInteger modulus = rsaPrivCrtKey.getModulus();
        int bitLength = modulus.bitLength();
        // rsapubkey.bitlen
        UnsignedUtil.putInt(bb, bitLength);
        BigInteger publicExponent = rsaPrivCrtKey.getPublicExponent();
        // rsapubkey.pubexp
        UnsignedUtil.putInt(bb, (int) publicExponent.longValue());
        /*
			 * Byte lengths divisions may have remainders to take account for if
			 * not factors of 16 and/or 8
			 */
        int add8 = 0;
        if ((bitLength % 8) != 0) {
            add8++;
        }
        int add16 = 0;
        if ((bitLength % 16) != 0) {
            add16++;
        }
        // modulus
        writeBigInteger(bb, modulus, (bitLength / 8) + add8);
        // prime1
        writeBigInteger(bb, rsaPrivCrtKey.getPrimeP(), (bitLength / 16) + add16);
        // prime2
        writeBigInteger(bb, rsaPrivCrtKey.getPrimeQ(), (bitLength / 16) + add16);
        // exponent1
        writeBigInteger(bb, rsaPrivCrtKey.getPrimeExponentP(), (bitLength / 16) + add16);
        // exponent2
        writeBigInteger(bb, rsaPrivCrtKey.getPrimeExponentQ(), (bitLength / 16) + add16);
        // coefficient
        writeBigInteger(bb, rsaPrivCrtKey.getCrtCoefficient(), (bitLength / 16) + add16);
        // privateExponent
        writeBigInteger(bb, rsaPrivCrtKey.getPrivateExponent(), (bitLength / 8) + add8);
        return getBufferBytes(bb);
    } catch (IOException ex) {
        throw new CryptoException(res.getString("NoConvertKeyToBlob.exception.message"), ex);
    }
}
Also used : BigInteger(java.math.BigInteger) IOException(java.io.IOException) CryptoException(org.kse.crypto.CryptoException) ByteBuffer(java.nio.ByteBuffer)

Example 59 with CryptoException

use of org.kse.crypto.CryptoException in project keystore-explorer by kaikramer.

the class MsPvkUtil method dsaPrivateKeyToBlob.

private static byte[] dsaPrivateKeyToBlob(DSAPrivateKey dsaPrivKey) throws CryptoException {
    try {
        DSAParams dsaParams = dsaPrivKey.getParams();
        // 328 sufficient for a 1024 bit DSA key
        ByteBuffer bb = ByteBuffer.wrap(new byte[512]);
        bb.order(ByteOrder.LITTLE_ENDIAN);
        // Write out the blob fields
        // dsspubkey.magic
        UnsignedUtil.putInt(bb, DSS_PRIV_MAGIC);
        BigInteger prime = dsaParams.getP();
        int bitLength = prime.toString(2).length();
        // dsspubkey.bitlen
        UnsignedUtil.putInt(bb, bitLength);
        /*
			 * Unlike RSA there are no bit length remainders (ie DSA bit length
			 * always divisible by 8 as they are multiples of 64)
			 */
        // modulus
        writeBigInteger(bb, dsaParams.getP(), (bitLength / 8));
        // prime
        writeBigInteger(bb, dsaParams.getQ(), 20);
        // generator
        writeBigInteger(bb, dsaParams.getG(), (bitLength / 8));
        // secret exponent
        writeBigInteger(bb, dsaPrivKey.getX(), 20);
        // dssseed.counter - none, fill 0xff
        UnsignedUtil.putInt(bb, 0xffffffff);
        for (// dssseed.seed - none, fill 0xff
        int i = 0; // dssseed.seed - none, fill 0xff
        i < 20; // dssseed.seed - none, fill 0xff
        i++) {
            bb.put((byte) 0xff);
        }
        return getBufferBytes(bb);
    } catch (IOException ex) {
        throw new CryptoException(res.getString("NoConvertKeyToBlob.exception.message"), ex);
    }
}
Also used : BigInteger(java.math.BigInteger) DSAParams(java.security.interfaces.DSAParams) IOException(java.io.IOException) CryptoException(org.kse.crypto.CryptoException) ByteBuffer(java.nio.ByteBuffer)

Example 60 with CryptoException

use of org.kse.crypto.CryptoException in project keystore-explorer by kaikramer.

the class MsPvkUtil method encryptPrivateKeyBlob.

private static byte[] encryptPrivateKeyBlob(byte[] privateKeyBlob, byte[] rc4Key) throws CryptoException {
    try {
        SecretKeySpec rc4KeySpec = new SecretKeySpec(rc4Key, "RC4");
        Cipher rc42 = Cipher.getInstance("RC4");
        rc42.init(Cipher.ENCRYPT_MODE, rc4KeySpec);
        return rc42.doFinal(privateKeyBlob);
    } catch (GeneralSecurityException ex) {
        throw new CryptoException(res.getString("PrivateKeyBlobRc4EncryptionFailed.exception.message"), ex);
    }
}
Also used : SecretKeySpec(javax.crypto.spec.SecretKeySpec) GeneralSecurityException(java.security.GeneralSecurityException) Cipher(javax.crypto.Cipher) CryptoException(org.kse.crypto.CryptoException)

Aggregations

CryptoException (org.kse.crypto.CryptoException)80 GeneralSecurityException (java.security.GeneralSecurityException)22 IOException (java.io.IOException)21 X509Certificate (java.security.cert.X509Certificate)21 KeyStore (java.security.KeyStore)16 KeyStoreException (java.security.KeyStoreException)13 BigInteger (java.math.BigInteger)11 DError (org.kse.gui.error.DError)10 ByteArrayInputStream (java.io.ByteArrayInputStream)9 File (java.io.File)9 DefaultMutableTreeNode (javax.swing.tree.DefaultMutableTreeNode)9 ByteBuffer (java.nio.ByteBuffer)8 CertificateException (java.security.cert.CertificateException)8 PrivateKey (java.security.PrivateKey)7 KeyFactory (java.security.KeyFactory)6 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)6 CertificateFactory (java.security.cert.CertificateFactory)6 DSAPrivateKey (java.security.interfaces.DSAPrivateKey)6 RSAPrivateCrtKey (java.security.interfaces.RSAPrivateCrtKey)6 Cipher (javax.crypto.Cipher)6