Example usage for org.bouncycastle.crypto.params KeyParameter getKey

List of usage examples for org.bouncycastle.crypto.params KeyParameter getKey

Introduction

In this page you can find the example usage for org.bouncycastle.crypto.params KeyParameter getKey.

Prototype

public byte[] getKey() 

Source Link

Usage

From source file:GenTestDKs.java

License:Open Source License

private static void testKey(PKCS12ParametersGenerator pgen, int keyLen, int iterCount, String password,
        byte[] salt) {
    System.out.println("key len = " + keyLen + ", iter count = " + iterCount + ", password = \"" + password
            + "\", salt len = " + salt.length);

    char[] pwChars = password.toCharArray();
    byte[] pwBytes = PBEParametersGenerator.PKCS12PasswordToBytes(pwChars);

    pgen.init(pwBytes, salt, iterCount);
    KeyParameter kp = (KeyParameter) pgen.generateDerivedParameters(keyLen);
    printByteArray(kp.getKey());
}

From source file:ch.lamacrypt.internal.crypto.CPCipher.java

License:Open Source License

/**
 * Initializes Poly1305 with the given instance of ChaCha20Engine
 *
 * @param cipher/*from ww  w  .j  a  v  a 2s  .  c  o m*/
 */
private void initMAC(ChaChaEngine cipher) {
    byte[] firstBlock = new byte[64];
    cipher.processBytes(firstBlock, 0, firstBlock.length, firstBlock, 0);

    // NOTE: The BC implementation puts 'r' after 'k'
    System.arraycopy(firstBlock, 0, firstBlock, 32, 16);
    KeyParameter macKey = new KeyParameter(firstBlock, 16, 32);
    Poly1305KeyGenerator.clamp(macKey.getKey());
    mac.init(macKey);
}

From source file:co.rsk.crypto.KeyCrypterAes.java

License:Open Source License

/**
 * Decrypt bytes previously encrypted with this class.
 *
 * @param dataToDecrypt    The data to decrypt
 * @param key              The AES key to use for decryption
 * @return                 The decrypted bytes
 * @throws                 KeyCrypterException if bytes could not be decrypted
 *///www .  j  a  va 2 s.c  o  m
@Override
public byte[] decrypt(EncryptedData dataToDecrypt, KeyParameter key) {
    checkNotNull(dataToDecrypt);
    checkNotNull(key);

    try {
        ParametersWithIV keyWithIv = new ParametersWithIV(new KeyParameter(key.getKey()),
                dataToDecrypt.initialisationVector);

        // Decrypt the message.
        BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()));
        cipher.init(false, keyWithIv);

        byte[] cipherBytes = dataToDecrypt.encryptedBytes;
        byte[] decryptedBytes = new byte[cipher.getOutputSize(cipherBytes.length)];
        final int length1 = cipher.processBytes(cipherBytes, 0, cipherBytes.length, decryptedBytes, 0);
        final int length2 = cipher.doFinal(decryptedBytes, length1);

        return Arrays.copyOf(decryptedBytes, length1 + length2);
    } catch (Exception e) {
        throw new KeyCrypterException("Could not decrypt bytes", e);
    }
}

From source file:cologne.eck.dr.op.crypto.password_hashing.Battcrypt_v0.java

License:Open Source License

@Override
public byte[] hashPassword(int outlen, byte[] in, byte[] salt, int t_cost, int m_cost, Object... varArgs)
        throws DataLengthException, IllegalStateException, InvalidCipherTextException {

    SHA512Digest sha = new SHA512Digest();
    int[] data = new int[DATA_SIZE_INT];
    BlowfishEngine blowfish;/*from   w  w w. j a v  a 2  s  .c om*/
    long upgradeLoops = 1;
    long loops;
    int memSize = 4 << m_cost;//= 4 * 2 ** m_cost
    int memMask = memSize - 1;
    int[] mem;

    byte[] hashBuffer = new byte[HASH_LENGTH_BYTE];// holds hash value as bytes
    byte[] dataBuffer = new byte[DATA_SIZE_BYTE];// holds encrypted bytes

    // These are the PHP max. values 
    if (m_cost > 18 || // maximum: 2.147.483.648 bytes
            (t_cost & 0xffff) > 62 || (t_cost >> 16) > 63 || outlen > HASH_LENGTH_BYTE) {
        throw new IllegalArgumentException("invalid parameters");
    }

    int tmp = t_cost >> 16;

    if (tmp != 0) {
        // upgradeLoops = 1, 2, 3, 4, 6, 8, 12, 16, ...
        upgradeLoops = (long) (3 - (tmp & 1)) << ((tmp - 1) >> 1);
    }

    // loops = 2, 3, 4, 6, 8, 12, 16, ...
    tmp = t_cost & 0xffff;
    loops = (long) ((tmp & 1) + 2) << (tmp >> 1);

    // key = SHA512(SHA512(salt) || in)
    byte[] keyBytes = new byte[HASH_LENGTH_BYTE];
    sha.update(salt, 0, salt.length);
    sha.doFinal(keyBytes, 0);
    sha.reset();
    sha.update(keyBytes, 0, HASH_LENGTH_BYTE);
    sha.update(in, 0, in.length);//password
    sha.doFinal(keyBytes, 0);
    sha.reset();
    if (wipePassword == true) {
        Arrays.fill(in, (byte) 0);
    }

    // initialize cipher with 448 bit (56 byte) key: 
    // truncate keyBytes:
    byte[] blowfishKey = new byte[56];
    System.arraycopy(keyBytes, 0, blowfishKey, 0, 56);
    // use zeros as IV
    byte[] iv = new byte[IV_LENGTH_BYTE];
    KeyParameter params = new KeyParameter(blowfishKey);
    Arrays.fill(blowfishKey, (byte) 0);
    ParametersWithIV ivParams = new ParametersWithIV(params, iv);
    blowfish = new BlowfishEngine();
    // CBC, no padding: all vectors are multiples of Blowfish block length
    BufferedBlockCipher cipher = new BufferedBlockCipher(new CBCBlockCipher(blowfish));
    cipher.init(true, ivParams);

    // initialize memory-hard vector:
    mem = new int[DATA_SIZE_INT * memSize];

    for (long u = 0; u < upgradeLoops; u++) {

        // initialize data:
        // data = SHA512(BIG_ENDIAN_64( 0) || key) || ...
        // ... || SHA512(BIG_ENDIAN_64(31) || key)         
        byte[] counterBytesBE = new byte[8]; // holds counter as long to update
        for (int i = 0; i < DATA_SIZE_BYTE / HASH_LENGTH_BYTE; i++) {

            counterBytesBE[7] = (byte) i; // set first byte
            sha.update(counterBytesBE, 0, counterBytesBE.length); // BIG_ENDIAN_64(i)
            sha.update(keyBytes, 0, HASH_LENGTH_BYTE);
            sha.doFinal(hashBuffer, 0);
            sha.reset();
            // hash values allow weak garbage collector attack - 
            // so, avoid new allocations:             
            for (int j = 0; j < HASH_LENGTH_BYTE / 4; j++) {
                data[HASH_LENGTH_INT * i + j] = ((hashBuffer[j * 4 + 3] & 0xFF) << 24)
                        | ((hashBuffer[j * 4 + 2] & 0xFF) << 16) | ((hashBuffer[j * 4 + 1] & 0xFF) << 8)
                        | (hashBuffer[j * 4 + 0] & 0xFF); // little endian order
            }
            Arrays.fill(hashBuffer, (byte) 0);
        }

        // Initialize memory:
        for (int i = 0; i < memSize; i++) {
            // data = blowfish_encrypt_cbc(data)
            // mem = mem || data            
            for (int j = 0; j < DATA_SIZE_INT; j++) {
                dataBuffer[j * 4 + 0] = (byte) (data[j]);// little endian
                dataBuffer[j * 4 + 1] = (byte) (data[j] >>> 8);
                dataBuffer[j * 4 + 2] = (byte) (data[j] >>> 16);
                dataBuffer[j * 4 + 3] = (byte) (data[j] >>> 24);
            }
            int len = cipher.processBytes(dataBuffer, 0, DATA_SIZE_BYTE, dataBuffer, 0);
            cipher.doFinal(dataBuffer, len);
            cipher.reset();

            // get iv for next encryption step:
            // "running CBC": the last block of the
            //  previous call is the IV for the next call
            System.arraycopy(dataBuffer, DATA_SIZE_BYTE - IV_LENGTH_BYTE, iv, 0, IV_LENGTH_BYTE);
            ivParams = new ParametersWithIV(params, iv);
            cipher.init(true, ivParams);

            for (int j = 0; j < DATA_SIZE_INT; j++) {
                data[j] = ((dataBuffer[j * 4 + 3] & 0xFF) << 24) | ((dataBuffer[j * 4 + 2] & 0xFF) << 16)
                        | ((dataBuffer[j * 4 + 1] & 0xFF) << 8) | (dataBuffer[j * 4 + 0] & 0xFF); // little endian order
            }
            System.arraycopy(data, 0, mem, DATA_SIZE_INT * i, DATA_SIZE_INT);
        }

        // encrypt data:
        for (int j = 0; j < DATA_SIZE_INT; j++) {
            dataBuffer[j * 4 + 0] = (byte) (data[j]);// little endian
            dataBuffer[j * 4 + 1] = (byte) (data[j] >>> 8);
            dataBuffer[j * 4 + 2] = (byte) (data[j] >>> 16);
            dataBuffer[j * 4 + 3] = (byte) (data[j] >>> 24);
        }
        int len = cipher.processBytes(dataBuffer, 0, DATA_SIZE_BYTE, dataBuffer, 0);
        cipher.doFinal(dataBuffer, len);
        cipher.reset();
        System.arraycopy(dataBuffer, DATA_SIZE_BYTE - IV_LENGTH_BYTE, iv, 0, IV_LENGTH_BYTE);
        ivParams = new ParametersWithIV(params, iv);
        cipher.init(true, ivParams);

        for (int j = 0; j < DATA_SIZE_INT; j++) {
            data[j] = ((dataBuffer[j * 4 + 3] & 0xFF) << 24) | ((dataBuffer[j * 4 + 2] & 0xFF) << 16)
                    | ((dataBuffer[j * 4 + 1] & 0xFF) << 8) | (dataBuffer[j * 4 + 0] & 0xFF); // little endian order
        }

        // work:
        for (long i = 0; i < loops; i++) {
            for (int j = 0; j < memSize; j++) {
                // in the C++ reference implementation and the paper 
                // this rValue a 64 bit integer, but this makes only a
                // difference for memSize > 0xFFFFFFFF +1, while the
                // recommended maximum for memSize is 2^32
                int rValue = ((((int) data[DATA_SIZE_INT - 1]) << 24) & 0xff000000)
                        | ((((int) data[DATA_SIZE_INT - 1]) << 8) & 0x00ff0000)
                        | ((((int) data[DATA_SIZE_INT - 1]) >>> 8) & 0x0000ff00)
                        | ((((int) data[DATA_SIZE_INT - 1]) >>> 24) & 0x000000ff);
                int index = (int) (DATA_SIZE_INT * (rValue & memMask));

                for (int k = 0; k < DATA_SIZE_INT; k++) {
                    mem[j * DATA_SIZE_INT + k] ^= data[k] ^ mem[index + k];
                }

                // convert to byte: 
                for (int k = 0; k < DATA_SIZE_INT; k++) {
                    dataBuffer[k * 4 + 0] = (byte) (mem[j * DATA_SIZE_INT + k]);
                    dataBuffer[k * 4 + 1] = (byte) (mem[j * DATA_SIZE_INT + k] >>> 8);
                    dataBuffer[k * 4 + 2] = (byte) (mem[j * DATA_SIZE_INT + k] >>> 16);
                    dataBuffer[k * 4 + 3] = (byte) (mem[j * DATA_SIZE_INT + k] >>> 24);
                }
                int len1 = cipher.processBytes(dataBuffer, 0, DATA_SIZE_BYTE, dataBuffer, 0);

                cipher.doFinal(dataBuffer, len1);
                cipher.reset();
                // get iv for next step:
                System.arraycopy(dataBuffer, DATA_SIZE_BYTE - IV_LENGTH_BYTE, iv, 0, IV_LENGTH_BYTE);

                for (int k = 0; k < DATA_SIZE_INT; k++) {
                    mem[j * DATA_SIZE_INT + k] = ((dataBuffer[k * 4 + 3] & 0xFF) << 24)
                            | ((dataBuffer[k * 4 + 2] & 0xFF) << 16) | ((dataBuffer[k * 4 + 1] & 0xFF) << 8)
                            | (dataBuffer[k * 4 + 0] & 0xFF); // little endian order
                }

                ivParams = new ParametersWithIV(params, iv);
                cipher.init(true, ivParams);

                // data ^= mem[j]
                for (int k = 0; k < DATA_SIZE_INT; k++) {
                    data[k] ^= mem[DATA_SIZE_INT * j + k];
                }
            }
        }
        // Finish
        // key = truncate(SHA512(SHA512(data || key)), outlen) || zeros(HASH_LENGTH - outlen)
        // convert to byte: 
        for (int k = 0; k < DATA_SIZE_INT; k++) {
            dataBuffer[k * 4 + 0] = (byte) (data[k]);
            dataBuffer[k * 4 + 1] = (byte) (data[k] >>> 8);
            dataBuffer[k * 4 + 2] = (byte) (data[k] >>> 16);
            dataBuffer[k * 4 + 3] = (byte) (data[k] >>> 24);
        }
        sha.update(dataBuffer, 0, DATA_SIZE_BYTE);
        sha.update(keyBytes, 0, HASH_LENGTH_BYTE);
        sha.doFinal(keyBytes, 0);
        sha.reset();
    }

    sha.update(keyBytes, 0, HASH_LENGTH_BYTE);
    sha.doFinal(keyBytes, 0);
    sha.reset();

    byte[] out = new byte[outlen];

    System.arraycopy(keyBytes, 0, out, 0, out.length);

    // Clean-up:
    Arrays.fill(keyBytes, (byte) 0);
    Arrays.fill(dataBuffer, (byte) 0);
    Arrays.fill(iv, (byte) 0);
    Arrays.fill(data, 0);
    Arrays.fill(mem, (byte) 0);

    // wipe the key from parameters
    Arrays.fill(params.getKey(), (byte) 0);

    // prevent dead code eliminations (compiler optimizations):
    if ((keyBytes[HASH_LENGTH_BYTE - 1] | blowfishKey[blowfishKey.length - 1] | dataBuffer[DATA_SIZE_BYTE - 1]
            | hashBuffer[HASH_LENGTH_BYTE - 1] | data[DATA_SIZE_INT - 1] | iv[IV_LENGTH_BYTE - 1]
            | mem[mem.length - 1] | params.getKey()[params.getKey().length - 1]) != 0) {
        System.err.print("zeroization failed!");
    }
    if ((wipePassword == true) && (in[in.length - 1] != 0)) {
        System.err.print("zeroization failed!");
    }
    return out;
}

From source file:cologne.eck.peafactory.crypto.CipherStuff.java

License:Open Source License

/**
 * Encrypt/decrypt an array of bytes. This function is only used to 
 * encrypt the session key/*from w  w  w.  j a  va 2 s  .  c  o m*/
 * 
 * @param forEncryption - true for encryption, false for decryption
 * @param input         - plain text or cipher text
 * @param key         - the cryptographic key for the cipher
 * @param zeroize      - fills the key with 0 for true (when the key is no longer used)
 * @return            - plain text or cipher text
 */
public final static byte[] processCTR(boolean forEncryption, byte[] input, byte[] key, boolean zeroize) {
    //Help.printBytes("key",  input);
    KeyParameter kp = new KeyParameter(key);
    if (zeroize == true) {
        Zeroizer.zero(key);
    }

    byte[] iv = null;

    if (forEncryption == false) {
        // input is ciphertext, IV is stored on top of ciphertext
        // get IV:
        iv = new byte[CipherStuff.getCipherAlgo().getBlockSize()];
        System.arraycopy(input, 0, iv, 0, iv.length);
        // truncate ciphertext:
        byte[] tmp = new byte[input.length - iv.length];
        System.arraycopy(input, iv.length, tmp, 0, tmp.length);
        input = tmp;
    } else {
        // input is plaintext
        iv = new RandomStuff().createRandomBytes(CipherStuff.getCipherAlgo().getBlockSize());
    }
    ParametersWithIV ivp = new ParametersWithIV(kp, iv);

    BufferedBlockCipher b = new BufferedBlockCipher(new SICBlockCipher(cipherAlgo));

    b.init(true, ivp);
    byte[] out = new byte[input.length];

    int len = b.processBytes(input, 0, input.length, out, 0);

    try {
        len += b.doFinal(out, len);
    } catch (DataLengthException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalStateException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvalidCipherTextException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    Zeroizer.zero(kp.getKey());

    if (forEncryption == false) {// decryption: output plaintext
        return out;
    } else { // encryption: output (IV || ciphertext)
        Zeroizer.zero(input);
        // store IV on top of ciphertext
        byte[] tmp = new byte[out.length + iv.length];
        System.arraycopy(iv, 0, tmp, 0, iv.length);
        System.arraycopy(out, 0, tmp, iv.length, out.length);
        return tmp;
    }
}

From source file:cologne.eck.peafactory.crypto.EAXMode.java

License:Open Source License

/**
 * Encrypt/decrypt an array of bytes/*  w w w .ja  va2  s .  c om*/
 * 
 * @param forEncryption - true for encryption, false for decryption
 * @param input         - plain text or cipher text
 * @param key         - the cryptographic key for the cipher
 * @param nonce         - unique Nonce of 8 byte
 * @return            - plain text or cipher text
 */
public final byte[] processBytes(boolean forEncryption, byte[] input, byte[] key, byte[] nonce) {

    int resultLen = 0;// proceeded bytes

    KeyParameter aeKey = new KeyParameter(key);

    int macLength = CipherStuff.getCipherAlgo().getBlockSize();
    if (macLength < 16) {
        System.out.println("Warning: short mac size: " + macLength);
    }

    EAXBlockCipher eaxCipher = new EAXBlockCipher(CipherStuff.getCipherAlgo());

    AEADParameters params = new AEADParameters(aeKey, macLength * 8, nonce);

    eaxCipher.init(forEncryption, params);

    byte[] result = new byte[eaxCipher.getOutputSize(input.length)];
    resultLen = eaxCipher.processBytes(input, 0, input.length, result, 0);
    try {
        resultLen += eaxCipher.doFinal(result, resultLen);
        // KeyParameter uses a copy of the key: 
        Zeroizer.zero(aeKey.getKey());
    } catch (IllegalStateException e) {
        CipherStuff.setErrorMessage("Internal application error");
        System.err.println("EAXMode - processBytes: " + e.toString());
        return null;
    } catch (InvalidCipherTextException e) {

        System.err.println("Authentication failed. ");
        if (PswDialogBase.getWorkingMode().equals("-r")) { // rescue mode

            Object[] options = { "Continue decryption despite error", "Do not decrypt" };
            int n = JOptionPane.showOptionDialog(null,
                    "Authentication failed:  \n" + "The content is not the previousely encrypted content. \n"
                            + "Normally that means, that the password is not correct, \n"
                            + "but there is the possibility that the file is damaged. \n"
                            + "In this case, some parts of the file might be restored \n"
                            + "by the decryption. \n" + "If you are sure, the password is correct, continue.\n"
                            + "Warning: For incorrect password files may be irretrievably lost. ",
                    "Authentication Error", JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE, null, options,
                    options[1]);

            if (n == JOptionPane.YES_OPTION) {
                return result;
            } else {
                return null;
            }
        } else {// not rescue mode
            CipherStuff.setErrorMessage("Authentication failed");
            return null;
        }
    } catch (Exception e) {
        CipherStuff.setErrorMessage("Unexpected error");
        return null;
    }
    return result;
}

From source file:cologne.eck.peafactory.crypto.EAXMode.java

License:Open Source License

/**
 * Encrypt an array of files//w w w.  j a  v a 2s.  c o  m
 * 
 * @param fileNames    array of file names
 * @param keyMaterial   derived material from KDF, contains the key
 * @param encryptBySessionKey   whether encrypt and store the derived key
 *                         or zeroize it
 * @param filePanel      JPanel to display the progress of encryption
 * @return            array of error messages, with the same indexing as fileNames
 */
public final String[] encryptFiles(String[] fileNames, byte[] keyMaterial, boolean encryptBySessionKey,
        FileTypePanel filePanel) {

    // Attachments: 
    // 1. Padding to plaintext
    // 2. pswIdentifier to ciphertext
    // 3. encryptedPswIdentifier to ciphertext
    // 4. nonce to ciphertext
    // (5. salt to ciphertext if bound == false)
    // 6. fileIdentifier to ciphertext

    //return value: 
    String[] errorMessages = new String[fileNames.length];

    //------------------
    // get the key: 
    //------------------
    byte[] keyBytes = CipherStuff.getInstance().detectKey(keyMaterial);
    KeyParameter key = new KeyParameter(keyBytes);

    int blockSize = CipherStuff.getCipherAlgo().getBlockSize();
    int macSize = blockSize;
    int nonceSize = Attachments.getNonceSize();

    EAXBlockCipher eaxCipher = new EAXBlockCipher(CipherStuff.getCipherAlgo());

    byte[] attachedSalt = null;
    int saltLen = 0;

    if (CipherStuff.isBound() == false) {

        if (KeyDerivation.getAttachedSalt() == null) {

            KeyDerivation.setSalt(Attachments.getProgramRandomBytes());
            attachedSalt = new RandomStuff().createRandomBytes(KeyDerivation.getSaltSize());
            // this will set attachedSalt and update the salt:
            KeyDerivation.setAttachedAndUpdateSalt(attachedSalt);
        }
        saltLen = KeyDerivation.getSaltSize();
    }

    //----------------------------------
    // encrypt the files:  
    // attach pswIdenitfier, do padding, 
    // encrypt block by block, 
    // attach IV, attach salt (if bound == false),
    // attach fileIdentifier
    //----------------------------------
    int progress = 0;

    for (int i = 0; i < fileNames.length; i++) {

        RandomAccessFile f = null;

        try {
            // update progress for each file (don't care about file length)
            filePanel.setProgressValue(progress);
            progress += 1000 / fileNames.length;

            if (new File(fileNames[i]).isDirectory()) {
                continue;
            }
            f = new RandomAccessFile(fileNames[i], "rwd");

            long fileSizeLong = f.length();
            if (fileSizeLong > (Integer.MAX_VALUE - (nonceSize * 2) // for pswIdentifier
                    - blockSize // mac 
                    - saltLen // o if bounded
                    - Attachments.getNonceSize())) {// Nonce
                errorMessages[i] = "file too large";
                continue;
            }
            int fileSize = (int) fileSizeLong;

            // random Nonce for each file
            byte[] nonce = Attachments.generateNonce();

            byte[] block = new byte[FILE_BLOCK_SIZE];

            // generate random pswIdentifier of 8 bytes:
            byte[] pswIdentifier = Attachments.generateNonce(); // 8 byte            

            AEADParameters idParams = new AEADParameters(key, 0, nonce, null);// no mac             
            eaxCipher.init(true, idParams);
            byte[] encryptedPswIdentifier = new byte[eaxCipher.getOutputSize(nonceSize)];

            // encrypt pswIdentifier without mac and store in 
            int processedIDBytes = eaxCipher.processBytes(pswIdentifier, 0, nonceSize, encryptedPswIdentifier,
                    nonceSize);
            eaxCipher.doFinal(encryptedPswIdentifier, processedIDBytes);
            eaxCipher.reset();

            fileSize = (int) f.length();
            // round down: get block number except last block
            int blockNumber = (fileSize / FILE_BLOCK_SIZE);
            if (fileSize % FILE_BLOCK_SIZE == 0) {
                blockNumber--;
            }

            if (macSize < 16) {
                System.out.println("Warning: short mac size: " + macSize);
            }
            AEADParameters params = new AEADParameters(key, macSize * 8, nonce, null);//associatedText);

            eaxCipher.init(true, params);

            int processedBytes = 0;

            // process the blocks:
            for (int j = 0; j < blockNumber; j++) { // only full blocks

                f.seek(j * FILE_BLOCK_SIZE);
                f.read(block, 0, FILE_BLOCK_SIZE);

                byte[] out = new byte[FILE_BLOCK_SIZE];

                processedBytes += eaxCipher.processBytes(block, 0, FILE_BLOCK_SIZE, out, 0);

                f.seek(j * FILE_BLOCK_SIZE);
                f.write(out, 0, FILE_BLOCK_SIZE);
            }

            // process the last (maybe only) block:
            f.seek(FILE_BLOCK_SIZE * blockNumber);
            int lastSize = fileSize - (FILE_BLOCK_SIZE * blockNumber);

            byte[] lastBlock = new byte[lastSize];

            f.read(lastBlock, 0, lastBlock.length);

            byte[] lastOut = new byte[eaxCipher.getOutputSize(lastSize)];

            processedBytes = 0;

            processedBytes += eaxCipher.processBytes(lastBlock, 0, lastSize, lastOut, 0);
            Zeroizer.zero(lastBlock);
            processedBytes += eaxCipher.doFinal(lastOut, processedBytes); // + extra + macSize

            f.seek(FILE_BLOCK_SIZE * blockNumber);
            f.write(lastOut, 0, lastOut.length);

            // add pswIdentifier to ciphertext file: 
            f.seek(f.length()); // set file pointer to end
            f.write(pswIdentifier, 0, pswIdentifier.length);
            f.seek(f.length());
            // add encryptedPswIdentifier to ciphertext file
            f.write(encryptedPswIdentifier, 0, encryptedPswIdentifier.length);

            // add nonce to ciphertext file
            Attachments.addNonce(f, nonce);

            if (CipherStuff.isBound() == false) {

                // if not bound: add salt to ciphertext file
                Attachments.addSalt(f, KeyDerivation.getAttachedSalt());
            }

            // add fileIdetifier to check later if this file was encrypted with this archive
            Attachments.addFileIdentifier(f);

            f.close();

        } catch (FileNotFoundException e) {
            errorMessages[i] = "file not found";
            System.err.println("EAXMode " + e.toString() + ", file: " + fileNames[i]);
            try {
                f.close();

            } catch (IOException e1) {
                e1.printStackTrace();
                errorMessages[i] += " - " + e1.toString();
                System.err.println("EAXMode " + e.toString() + ", file: " + fileNames[i]);
                try {
                    eaxCipher.reset();
                } catch (Exception e2) {
                    System.err.println("EAXMode: Cipher reset failed");
                }
                continue;
            } catch (NullPointerException npe) {
                errorMessages[i] += " - file is probably used by other program";
                System.err.println("EAXMode " + e.toString() + ", file: " + fileNames[i]);
                try {
                    eaxCipher.reset();
                } catch (Exception e1) {
                    System.err.println("EAXMode: Cipher reset failed");
                }
                continue;
            }
            try {
                eaxCipher.reset();
            } catch (Exception e1) {
                System.err.println("EAXMode: Cipher reset failed");
            }
            continue;
            //e.printStackTrace();
        } catch (IOException e) {
            errorMessages[i] = "read/write failed";
            System.err.println("CryptStuff " + e.toString() + ", file: " + fileNames[i]);
            try {
                f.close();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
                errorMessages[i] += " - " + e1.toString();
                System.err.println("EAXMode " + e.toString() + ", file: " + fileNames[i]);
                eaxCipher.reset();
                continue;
            }
            try {
                eaxCipher.reset();
            } catch (Exception e1) {
                System.err.println("EAXMode: Cipher reset failed");
            }
            continue;
            //e.printStackTrace();
        } catch (Exception e) {
            errorMessages[i] = "unexpected error: " + e.getMessage();
            System.err.println("CryptStuff " + e.toString() + ", file: " + fileNames[i]);
            e.printStackTrace();
            try {
                f.close();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
                errorMessages[i] += " - " + e1.toString();
                System.err.println("EAXMode " + e.toString() + ", file: " + fileNames[i]);
                eaxCipher.reset();
                continue;
            }
            try {
                eaxCipher.reset();
            } catch (Exception e1) {
                System.err.println("EAXMode: Cipher reset failed");
            }
            continue;
            //e.printStackTrace();         
        }
        eaxCipher.reset();
    } // end for      

    //-----------------
    // Handle the keys:
    // encrypt or fill
    //-----------------
    CipherStuff.getInstance().handleKey(key.getKey(), encryptBySessionKey);

    return errorMessages;
}

From source file:cologne.eck.peafactory.crypto.EAXMode.java

License:Open Source License

/**
 * Decrypt an array of files//from w  ww.  jav a 2 s. co  m
 * 
 * @param fileNames    array of file names
 * @param keyMaterial   derived material from KDF, contains the key
 * @param encryptBySessionKey   whether encrypt and store the derived key
 *                         or zeroize it
 * @param filePanel      JPanel to display the progress of encryption
 * @return            array of error messages, with the same indexing as fileNames
 */
public final String[] decryptFiles(String[] fileNames, byte[] keyMaterial, boolean encryptBySessionKey,
        FileTypePanel filePanel) {

    int fileNamesLen = fileNames.length;

    //return value: 
    String[] errorMessages = new String[fileNamesLen];

    // Attachments: 
    // 1. cut fileIdentifier from ciphertext
    // (2. cut salt from Ciphertext if bound == false)
    // 3. cut nonce from ciphertext
    // 4. cut encryptedPswIdentifier from ciphertext
    // 5. cut pswIdentifier from ciphertext
    // 6. undo padding

    //------------------
    // get the key: 
    //------------------
    byte[] keyBytes = CipherStuff.getInstance().detectKey(keyMaterial);
    KeyParameter key = new KeyParameter(keyBytes);

    int blockSize = CipherStuff.getCipherAlgo().getBlockSize();
    int macSize = blockSize;
    int nonceSize = Attachments.getNonceSize();

    int blockNumber = 0;

    EAXBlockCipher eaxCipher = new EAXBlockCipher(CipherStuff.getCipherAlgo());

    //----------------------------------
    // decrypt the files: 
    // decrypt block by block, 
    // add short plain text and cipher text to check password
    // attach Nonce, attach fileIdentifier
    //----------------------------------
    int progress = 0;

    int saltLen = 0;
    if (CipherStuff.isBound() == false) {
        saltLen = KeyDerivation.getSaltSize();
    }

    for (int i = 0; i < fileNamesLen; i++) {

        RandomAccessFile f = null;
        byte[] lastNonce = null;// to add if error occurs
        int blockCounter = 0;// to get block where authentication failed

        try {

            // update progress for each file (don't care about file length)
            filePanel.setProgressValue(progress);
            progress += 1000 / fileNamesLen;

            if (new File(fileNames[i]).isDirectory()) {
                continue;
            }
            f = new RandomAccessFile(fileNames[i], "rwd");

            int fileSize = (int) f.length();
            if (fileSize < (macSize + (nonceSize * 3) // Nonce + pswId + encPswId  
                    + saltLen // 0 if bounded
                    + Attachments.getFileIdentifierSize())) {
                errorMessages[i] = "inappropriate file (length)";
                System.err.println("file size < minimum: " + fileNames[i]);
                f.close();
                continue;
            }
            // cut fileIdentifier
            if (Attachments.checkFileIdentifier(f, true) == false) { // truncates if true
                errorMessages[i] = "inappropriate file (identifier)";
                System.err.println("file identifier failed: " + fileNames[i]);
                f.close();
                continue;
            }
            // cut the salt
            if (CipherStuff.isBound() == false) {

                byte[] attachedSalt = Attachments.getAndCutSalt(f, true);

                if (Comparator.compare(attachedSalt, KeyDerivation.getAttachedSalt()) == false) {

                    errorMessages[i] = "salt differs from first selected file";
                    System.err.println("different salt: " + fileNames[i]);
                    f.close();
                    if (i == fileNamesLen - 1) {
                        return errorMessages;
                    } else {
                        continue;
                    }
                }
            }
            // get and cut random Nonce for each file
            byte[] nonce = Attachments.getAndCutNonce(f, true);
            lastNonce = nonce;

            // Check and cut pswIdentifier:
            f.seek(f.length() - (nonceSize * 2));// 
            byte[] bytesToCheckPswIdentifier = new byte[nonceSize * 2];
            f.read(bytesToCheckPswIdentifier);
            byte[] pswIdentifier = new byte[nonceSize];
            byte[] encryptedPswIdentifier = new byte[nonceSize];
            System.arraycopy(bytesToCheckPswIdentifier, 0, pswIdentifier, 0, nonceSize);
            System.arraycopy(bytesToCheckPswIdentifier, nonceSize, encryptedPswIdentifier, 0, nonceSize);

            AEADParameters idParams = new AEADParameters(key, 0, nonce, null);// no mac             
            eaxCipher.init(false, idParams);
            byte[] decryptedPswIdentifier = new byte[eaxCipher.getOutputSize(nonceSize)];

            int procesedIDBytes = eaxCipher.processBytes(encryptedPswIdentifier, 0, nonceSize,
                    decryptedPswIdentifier, nonceSize);
            eaxCipher.doFinal(decryptedPswIdentifier, procesedIDBytes);

            // compare:
            boolean check = Comparator.compare(pswIdentifier, decryptedPswIdentifier);

            if (check == false) {
                errorMessages[i] = "password failed";
                System.out.println("password failed: identifier not equal");
                try {
                    Attachments.addNonce(f, nonce);
                    if (CipherStuff.isBound() == false) {
                        Attachments.addSalt(f, KeyDerivation.getAttachedSalt());
                    }
                    Attachments.addFileIdentifier(f);
                    f.close();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                eaxCipher.reset();
                continue;
            } else {
                f.setLength(f.length() - (nonceSize * 2));
            }
            eaxCipher.reset();

            byte[] block = new byte[FILE_BLOCK_SIZE];
            fileSize = (int) f.length();
            // round down: get block number except last block
            blockNumber = ((fileSize - macSize) / FILE_BLOCK_SIZE);
            if ((fileSize - macSize) % FILE_BLOCK_SIZE == 0) {
                blockNumber--;
            }

            //   byte[] associatedText = Attachments.getFileIdentifier();// 8 byte, not really necessary
            AEADParameters params = new AEADParameters(key, macSize * 8, nonce, null);//associatedText);

            eaxCipher.init(false, params);

            int processedBytes = 0;

            // process the blocks:
            for (blockCounter = 0; blockCounter < blockNumber; blockCounter++) { // only full blocks

                f.seek(blockCounter * FILE_BLOCK_SIZE);
                f.read(block, 0, FILE_BLOCK_SIZE);

                byte[] out = new byte[FILE_BLOCK_SIZE];
                processedBytes += eaxCipher.processBytes(block, 0, FILE_BLOCK_SIZE, out, 0);

                f.seek(blockCounter * FILE_BLOCK_SIZE);
                f.write(out, 0, FILE_BLOCK_SIZE);
            }

            // process the last (maybe only) block:
            f.seek(FILE_BLOCK_SIZE * blockNumber);

            byte[] lastBlock = new byte[fileSize - (FILE_BLOCK_SIZE * blockNumber)];
            f.read(lastBlock, 0, lastBlock.length);

            byte[] lastOut = new byte[eaxCipher.getOutputSize(lastBlock.length)];
            processedBytes = 0; // reset            
            processedBytes += eaxCipher.processBytes(lastBlock, 0, lastBlock.length, lastOut, 0);
            processedBytes += eaxCipher.doFinal(lastOut, processedBytes); // + macSize

            f.seek(FILE_BLOCK_SIZE * blockNumber);
            f.write(lastOut, 0, lastOut.length);

            // truncate file (mac and extra bytes):
            f.setLength(FILE_BLOCK_SIZE * blockNumber + lastOut.length);

            f.close();

        } catch (FileNotFoundException e) {
            errorMessages[i] = "file not found";
            System.err.println("EAXMode " + e.toString() + ", file: " + fileNames[i]);
            try {
                Attachments.addNonce(f, lastNonce);
                Attachments.addFileIdentifier(f);
                f.close();
            } catch (IOException e1) {
                e1.printStackTrace();
                errorMessages[i] += " - " + e1.toString();
                System.err.println("EAXMode " + e.toString() + ", file: " + fileNames[i]);
                try {
                    eaxCipher.reset();
                } catch (Exception e2) {
                    System.err.println("EAXMode: Cipher reset failed");
                }
                continue;

            }
            try {
                eaxCipher.reset();
            } catch (Exception e1) {
                System.err.println("EAXMode: Cipher reset failed");
            }
            continue;
            //e.printStackTrace();
        } catch (IOException e) {
            errorMessages[i] = "read/write failed";
            System.err
                    .println("CryptStuff " + e.toString() + ": " + e.getMessage() + ", file: " + fileNames[i]);
            try {
                Attachments.addNonce(f, lastNonce);
                Attachments.addFileIdentifier(f);
                f.close();
            } catch (IOException e1) {
                e1.printStackTrace();
                errorMessages[i] += " - " + e1.toString();
                System.err.println("EAXMode " + e.toString() + ", file: " + fileNames[i]);
                try {
                    eaxCipher.reset();
                } catch (Exception e2) {
                    System.err.println("EAXMode: Cipher reset failed");
                }
                continue;
            }
            eaxCipher.reset();
            continue;
            //e.printStackTrace();
        } catch (InvalidCipherTextException icte) {// Authentication failed

            if (PswDialogBase.getWorkingMode().equals("-r")) { // rescue mode: 
                System.out.println("===============   Corrupted file   =====================");
                System.out.println("Authentication failed, block: " + blockCounter + "  file: " + fileNames[i]);
                System.out.println("========================================================\n");
            } else {// try to undo decryption:
                JOptionPane.showMessageDialog(PswDialogView.getView(),
                        "The file \n" + fileNames[i] + "\n has been corrupted at block " + blockCounter
                                + ".\n\n"
                                + "The reason may be a simple error of the medium or a targeted manipulation.\n"
                                + "The Decryption of the file is cancelled. \n"
                                + "The program will now try to restore the original state.\n"
                                + "You can run this pea in rescue mode to decrypt this file anyway:\n "
                                + "java -jar " + PeaSettings.getJarFileName() + ".jar -r",
                        "Authentication failed", JOptionPane.ERROR_MESSAGE);
                errorMessages[i] = "authentication failed - encrypted file was corrupted";
                System.err.println("CryptStuff " + icte.toString() + ", file: " + fileNames[i]);
                System.err.println(
                        "You can try to run in rescue modus (Parameter -r)\n java -jar THIS_PEA.jar -r");
                System.out.println("===============   Corrupted file   =====================");
                System.out.println(
                        "You can try to run in rescue modus (Parameter -r)\n java -jar THIS_PEA.jar -r");
                System.out.println("========================================================");
                //icte.printStackTrace();
                try {
                    if (blockNumber == 0) { // only last block, nothing was written
                        Attachments.addNonce(f, lastNonce);
                        if (CipherStuff.isBound() == false) {
                            Attachments.addSalt(f, KeyDerivation.getAttachedSalt());
                        }
                        Attachments.addFileIdentifier(f);
                        f.close();
                    } else {
                        System.out.println("Try to undo decryption...");
                        // encrypt blocks
                        AEADParameters params = new AEADParameters(key, macSize * 8, lastNonce, null);//associatedText);                
                        eaxCipher.init(true, params);
                        // process the blocks:
                        byte[] repairBlock = new byte[FILE_BLOCK_SIZE];
                        for (int j = 0; j < blockCounter; j++) { // only full blocks
                            f.seek(j * FILE_BLOCK_SIZE);
                            f.read(repairBlock, 0, FILE_BLOCK_SIZE);
                            byte[] out = new byte[FILE_BLOCK_SIZE];
                            eaxCipher.processBytes(repairBlock, 0, FILE_BLOCK_SIZE, out, 0);
                            f.seek(j * FILE_BLOCK_SIZE);
                            f.write(out, 0, FILE_BLOCK_SIZE);
                        }
                        // generate pswIdentifier:
                        byte[] pswId = Attachments.generateNonce(); // 8 byte             
                        AEADParameters idParams = new AEADParameters(key, 0, lastNonce, null);// no mac             
                        eaxCipher.init(true, idParams);
                        byte[] idOut = new byte[eaxCipher.getOutputSize(pswId.length)];
                        int procesedIDBytes = eaxCipher.processBytes(pswId, 0, pswId.length, idOut,
                                pswId.length);
                        eaxCipher.doFinal(idOut, procesedIDBytes);
                        eaxCipher.reset();
                        // ad pswIdentifier: 
                        f.seek(f.length()); // set file pointer to end
                        f.write(pswId, 0, pswId.length);
                        f.seek(f.length());
                        f.write(idOut, 0, idOut.length);

                        Attachments.addNonce(f, lastNonce);
                        if (CipherStuff.isBound() == false) {
                            Attachments.addSalt(f, KeyDerivation.getAttachedSalt());
                        }
                        Attachments.addFileIdentifier(f);

                        f.close();
                        eaxCipher.reset();
                        continue;
                    }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    errorMessages[i] += " - " + e.toString();
                    System.err.println("EAXMode " + e.toString() + ", file: " + fileNames[i]);
                    try {
                        eaxCipher.reset();
                    } catch (Exception e1) {
                        System.err.println("EAXMode: Cipher reset failed");
                    }
                    continue;
                }
                try {
                    eaxCipher.reset();
                } catch (Exception e1) {
                    System.err.println("EAXMode: Cipher reset failed");
                }
                continue;
                //e.printStackTrace();
            }
        } catch (Exception e) {
            errorMessages[i] = "unexpected error: " + e.getMessage();
            System.err
                    .println("CryptStuff " + e.toString() + ": " + e.getMessage() + ", file: " + fileNames[i]);
            try {
                Attachments.addNonce(f, lastNonce);
                if (CipherStuff.isBound() == false) {
                    Attachments.addSalt(f, KeyDerivation.getAttachedSalt());
                }
                Attachments.addFileIdentifier(f);
                f.close();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            try {
                eaxCipher.reset();
            } catch (Exception e1) {
                System.err.println("EAXMode: Cipher reset failed");
            }
            continue;
            //e.printStackTrace();         
        }
        eaxCipher.reset();
    } // end for      

    //---------------
    // Handle keys:
    // encrypt or fill
    //----------------
    CipherStuff.getInstance().handleKey(key.getKey(), encryptBySessionKey);

    return errorMessages;
}

From source file:com.google.bitcoin.crypto.KeyCrypterScrypt.java

License:MIT License

/**
 * Decrypt bytes previously encrypted with this class.
 *
 * @param privateKeyToDecode    The private key to decrypt
 * @param aesKey           The AES key to use for decryption
 * @return                 The decrypted bytes
 * @throws                 KeyCrypterException if bytes could not be decoded to a valid key
 *///from w w  w  . ja va2  s . c  om
@Override
public byte[] decrypt(EncryptedPrivateKey privateKeyToDecode, KeyParameter aesKey) throws KeyCrypterException {
    checkNotNull(privateKeyToDecode);
    checkNotNull(aesKey);

    try {
        ParametersWithIV keyWithIv = new ParametersWithIV(new KeyParameter(aesKey.getKey()),
                privateKeyToDecode.getInitialisationVector());

        // Decrypt the message.
        BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESFastEngine()));
        cipher.init(false, keyWithIv);

        byte[] cipherBytes = privateKeyToDecode.getEncryptedBytes();
        byte[] decryptedBytes = new byte[cipher.getOutputSize(cipherBytes.length)];
        final int length1 = cipher.processBytes(cipherBytes, 0, cipherBytes.length, decryptedBytes, 0);
        final int length2 = cipher.doFinal(decryptedBytes, length1);

        return Arrays.copyOf(decryptedBytes, length1 + length2);
    } catch (Exception e) {
        throw new KeyCrypterException("Could not decrypt bytes", e);
    }
}

From source file:com.netflix.msl.crypto.JsonWebEncryptionCryptoContext.java

License:Open Source License

@Override
public byte[] wrap(final byte[] data) throws MslCryptoException {
    // Create the header.
    final String header;
    try {//from  ww w .  j a v a 2s.co m
        header = new JSONStringer().object().key(KEY_ALGORITHM).value(algo.toString()).key(KEY_ENCRYPTION)
                .value(enc.name()).endObject().toString();
    } catch (final JSONException e) {
        throw new MslCryptoException(MslError.JWE_ENCODE_ERROR, e);
    }

    // Determine algorithm byte lengths.
    final int keylen, ivlen, atlen;
    if (Encryption.A128GCM.equals(enc)) {
        keylen = A128_GCM_KEY_LENGTH;
        ivlen = A128_GCM_IV_LENGTH;
        atlen = A128_GCM_AT_LENGTH;
    } else if (Encryption.A256GCM.equals(enc)) {
        keylen = A256_GCM_KEY_LENGTH;
        ivlen = A256_GCM_IV_LENGTH;
        atlen = A256_GCM_AT_LENGTH;
    } else {
        throw new MslCryptoException(MslError.UNSUPPORTED_JWE_ALGORITHM, enc.name());
    }

    // Generate the key and IV.
    final Random random = ctx.getRandom();
    final byte[] key = new byte[keylen];
    random.nextBytes(key);
    final KeyParameter cek = new KeyParameter(key);
    final byte[] iv = new byte[ivlen];
    random.nextBytes(iv);

    // Encrypt the CEK.
    final byte[] ecek = cekCryptoContext.encrypt(cek.getKey());

    // Base64-encode the data.
    final String headerB64 = JsonUtils.b64urlEncode(header.getBytes(UTF_8));
    final String ecekB64 = JsonUtils.b64urlEncode(ecek);
    final String ivB64 = JsonUtils.b64urlEncode(iv);

    // Create additional authenticated data.
    final String aad = headerB64 + "." + ecekB64 + "." + ivB64;

    // TODO: AES-GCM is not available via the JCE.
    //
    // Create and initialize the cipher for encryption.
    final GCMBlockCipher plaintextCipher = new GCMBlockCipher(new AESEngine());
    final AEADParameters params = new AEADParameters(cek, atlen, iv, aad.getBytes(UTF_8));
    plaintextCipher.init(true, params);

    // Encrypt the plaintext.
    final byte[] ciphertextATag;
    try {
        final int clen = plaintextCipher.getOutputSize(data.length);
        ciphertextATag = new byte[clen];
        // Encrypt the plaintext and get the resulting ciphertext length
        // which will be used for the authentication tag offset.
        final int offset = plaintextCipher.processBytes(data, 0, data.length, ciphertextATag, 0);
        // Append the authentication tag.
        plaintextCipher.doFinal(ciphertextATag, offset);
    } catch (final IllegalStateException e) {
        throw new MslCryptoException(MslError.WRAP_ERROR, e);
    } catch (final InvalidCipherTextException e) {
        throw new MslInternalException("Invalid ciphertext not expected when encrypting.", e);
    }

    // Split the result into the ciphertext and authentication tag.
    final byte[] ciphertext = Arrays.copyOfRange(ciphertextATag, 0, ciphertextATag.length - atlen / Byte.SIZE);
    final byte[] at = Arrays.copyOfRange(ciphertextATag, ciphertext.length, ciphertextATag.length);

    // Base64-encode the ciphertext and authentication tag.
    final String ciphertextB64 = JsonUtils.b64urlEncode(ciphertext);
    final String atB64 = JsonUtils.b64urlEncode(at);

    // Envelope the data.
    switch (format) {
    case JWE_CS: {
        final String serialization = aad + "." + ciphertextB64 + "." + atB64;
        return serialization.getBytes(UTF_8);
    }
    case JWE_JS: {
        try {
            // Create recipients array.
            final JSONArray recipients = new JSONArray();
            final JSONObject recipient = new JSONObject();
            recipient.put(KEY_HEADER, headerB64);
            recipient.put(KEY_ENCRYPTED_KEY, ecekB64);
            recipient.put(KEY_INTEGRITY_VALUE, atB64);
            recipients.put(recipient);

            // Create JSON serialization.
            final JSONObject serialization = new JSONObject();
            serialization.put(KEY_RECIPIENTS, recipients);
            serialization.put(KEY_INITIALIZATION_VECTOR, ivB64);
            serialization.put(KEY_CIPHERTEXT, ciphertextB64);
            return serialization.toString().getBytes(UTF_8);
        } catch (final JSONException e) {
            throw new MslCryptoException(MslError.JWE_ENCODE_ERROR, e);
        }
    }
    default:
        throw new MslCryptoException(MslError.UNSUPPORTED_JWE_SERIALIZATION, format.name());
    }
}