Example usage for org.bouncycastle.crypto.params AEADParameters AEADParameters

List of usage examples for org.bouncycastle.crypto.params AEADParameters AEADParameters

Introduction

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

Prototype

public AEADParameters(KeyParameter key, int macSize, byte[] nonce, byte[] associatedText) 

Source Link

Document

Base constructor.

Usage

From source file:NoekeonVects.java

License:Creative Commons License

public void eax_vectors() throws Exception {
    System.out.println("EAX-noekeon (16 byte key)");
    EAXBlockCipher eax = new EAXBlockCipher(new NoekeonEngine());
    byte[] output = new byte[48];
    byte[] tag = new byte[16];

    for (int j = 0; j < 16; j++)
        tag[j] = (byte) j;

    for (int i = 0; i <= 32; i++) {
        byte[] header_nonce_plaintext = new byte[i];
        for (int j = 0; j < i; j++)
            header_nonce_plaintext[j] = (byte) j;
        AEADParameters params = new AEADParameters(maybe_schedule_key(tag), 128, header_nonce_plaintext,
                header_nonce_plaintext);
        eax.init(true, params);/*from   w ww  .j a  v a  2  s  .  c  o m*/
        int off = eax.processBytes(header_nonce_plaintext, 0, i, output, 0);
        off += eax.doFinal(output, off);
        if (off != i + 16)
            throw new RuntimeException("didn't expect that");
        byte[] ciphertext = new byte[i];
        for (int j = 0; j < i; j++)
            ciphertext[j] = output[j];
        for (int j = 0; j < 16; j++)
            tag[j] = output[i + j];
        System.out.print(i < 10 ? "  " : " ");
        System.out.print(i);
        System.out.print(": ");
        hexOut(ciphertext);
        System.out.print(", ");
        hexOut(tag);
        System.out.println();
    }
}

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

License:Open Source License

/**
 * Encrypt an array of files//from  ww  w .ja  v  a  2 s.  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 . j ava  2  s  .com*/
 * 
 * @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.github.horrorho.inflatabledonkey.crypto.AESGCM.java

License:Open Source License

/**
 * Returns decrypted data.//  www.  j  a va 2 s. c o m
 *
 * @param key
 * @param nonce nonce/ IV
 * @param header
 * @param encryptedData
 * @param tag
 * @param optional optional AADBytes (post header)
 * @return decrypted data
 * @throws IllegalArgumentException on decryption exceptions
 * @throws NullPointerException on null arguments
 */
public static byte[] decrypt(byte[] key, byte[] nonce, byte[] header, byte[] encryptedData, byte[] tag,
        Optional<byte[]> optional) {

    try {
        GCMBlockCipher cipher = new GCMBlockCipher(new AESFastEngine());
        AEADParameters parameters = new AEADParameters(new KeyParameter(key), tag.length * 8, nonce, header);
        cipher.init(false, parameters);

        if (optional.isPresent()) {
            byte[] aadBytes = optional.get();
            cipher.processAADBytes(aadBytes, 0, aadBytes.length);
        }

        byte[] out = new byte[cipher.getOutputSize(encryptedData.length + tag.length)];

        int pos = cipher.processBytes(encryptedData, 0, encryptedData.length, out, 0);
        pos += cipher.processBytes(tag, 0, tag.length, out, pos);
        pos += cipher.doFinal(out, pos);

        return Arrays.copyOf(out, pos);

    } catch (IllegalStateException | InvalidCipherTextException ex) {
        throw new IllegalStateException("GCM decrypt error", ex);
    }
}

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 {//w w  w .j  ava  2 s  .c o 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());
    }
}

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

License:Open Source License

@Override
public byte[] unwrap(final byte[] data) throws MslCryptoException {
    // Parse the serialization.
    final String serialization = new String(data, UTF_8);
    final String headerB64, ecekB64, ivB64;
    final byte[] ciphertext, at;
    if (data[0] == '{') {
        try {/*w ww . j  a  v  a 2s  . co  m*/
            final JSONObject serializationJo = new JSONObject(serialization);
            ivB64 = serializationJo.getString(KEY_INITIALIZATION_VECTOR);
            ciphertext = JsonUtils.b64urlDecode(serializationJo.getString(KEY_CIPHERTEXT));

            // TODO: For now, we only support one recipient.
            final JSONArray recipients = serializationJo.getJSONArray(KEY_RECIPIENTS);
            final JSONObject recipient = recipients.getJSONObject(0);
            headerB64 = recipient.getString(KEY_HEADER);
            ecekB64 = recipient.getString(KEY_ENCRYPTED_KEY);
            at = JsonUtils.b64urlDecode(recipient.getString(KEY_INTEGRITY_VALUE));
        } catch (final JSONException e) {
            throw new MslCryptoException(MslError.JWE_PARSE_ERROR, serialization, e);
        }
    } else {
        // Separate the compact serialization.
        final String[] parts = serialization.split("\\.");
        if (parts.length != 5)
            throw new MslCryptoException(MslError.JWE_PARSE_ERROR, serialization);

        // Extract the data from the serialization.
        headerB64 = parts[0];
        ecekB64 = parts[1];
        ivB64 = parts[2];
        ciphertext = JsonUtils.b64urlDecode(parts[3]);
        at = JsonUtils.b64urlDecode(parts[4]);
    }

    // Decode header, encrypted content encryption key, and IV.
    final byte[] headerBytes = JsonUtils.b64urlDecode(headerB64);
    final byte[] ecek = JsonUtils.b64urlDecode(ecekB64);
    final byte[] iv = JsonUtils.b64urlDecode(ivB64);

    // Verify data.
    if (headerBytes == null || headerBytes.length == 0 || ecek == null || ecek.length == 0 || iv == null
            || iv.length == 0 || ciphertext == null || ciphertext.length == 0 || at == null || at.length == 0) {
        throw new MslCryptoException(MslError.JWE_PARSE_ERROR, serialization);
    }

    // Reconstruct and parse the header.
    final String header = new String(headerBytes, UTF_8);
    final Algorithm algo;
    final Encryption enc;
    try {
        final JSONObject headerJo = new JSONObject(header);
        final String algoName = headerJo.getString(KEY_ALGORITHM);
        try {
            algo = Algorithm.fromString(algoName);
        } catch (final IllegalArgumentException e) {
            throw new MslCryptoException(MslError.JWE_PARSE_ERROR, algoName, e);
        }
        final String encName = headerJo.getString(KEY_ENCRYPTION);
        try {
            enc = Encryption.valueOf(encName);
        } catch (final IllegalArgumentException e) {
            throw new MslCryptoException(MslError.JWE_PARSE_ERROR, encName, e);
        }
    } catch (final JSONException e) {
        throw new MslCryptoException(MslError.JWE_PARSE_ERROR, header, e);
    }

    // Confirm header matches.
    if (!this.algo.equals(algo) || !this.enc.equals(enc))
        throw new MslCryptoException(MslError.JWE_ALGORITHM_MISMATCH, header);

    // Decrypt the CEK.
    final KeyParameter cek;
    try {
        final byte[] cekBytes = cekCryptoContext.decrypt(ecek);
        cek = new KeyParameter(cekBytes);
    } catch (final ArrayIndexOutOfBoundsException e) {
        // Thrown if the encrypted content encryption key is an invalid
        // length.
        throw new MslCryptoException(MslError.INVALID_SYMMETRIC_KEY, e);
    }

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

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

    // Verify algorithm parameters.
    if (cek.getKey().length != keylen)
        throw new MslCryptoException(MslError.INVALID_SYMMETRIC_KEY,
                "content encryption key length: " + cek.getKey().length);
    if (at.length != atlen / Byte.SIZE)
        throw new MslCryptoException(MslError.INVALID_ALGORITHM_PARAMS,
                "authentication tag length: " + at.length);

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

    // Decrypt the ciphertext.
    try {
        // Reconstruct the ciphertext and authentication tag.
        final byte[] ciphertextAtag = Arrays.copyOf(ciphertext, ciphertext.length + at.length);
        System.arraycopy(at, 0, ciphertextAtag, ciphertext.length, at.length);
        int plen = plaintextCipher.getOutputSize(ciphertextAtag.length);
        byte[] plaintext = new byte[plen];
        // Decrypt the ciphertext and get the resulting plaintext length
        // which will be used for the authentication tag offset.
        int offset = plaintextCipher.processBytes(ciphertextAtag, 0, ciphertextAtag.length, plaintext, 0);
        // Verify the authentication tag.
        plaintextCipher.doFinal(plaintext, offset);
        return plaintext;
    } catch (final IllegalStateException e) {
        throw new MslCryptoException(MslError.UNWRAP_ERROR, e);
    } catch (final InvalidCipherTextException e) {
        throw new MslCryptoException(MslError.UNWRAP_ERROR, e);
    } catch (final ArrayIndexOutOfBoundsException e) {
        // Thrown if the ciphertext is an invalid length.
        throw new MslCryptoException(MslError.UNWRAP_ERROR, e);
    }
}

From source file:com.nimbusds.jose.crypto.impl.LegacyAESGCM.java

License:Apache License

/**
 * Creates a new AES/GCM/NoPadding cipher.
 *
 * @param secretKey     The AES key. Must not be {@code null}.
 * @param forEncryption If {@code true} creates an encryption cipher,
 *                      else creates a decryption cipher.
 * @param iv            The initialisation vector (IV). Must not be
 *                      {@code null}./*from  ww  w .  j  av a2s.  c  o m*/
 * @param authData      The authenticated data. Must not be
 *                      {@code null}.
 *
 * @return The AES/GCM/NoPadding cipher.
 */
private static GCMBlockCipher createAESGCMCipher(final SecretKey secretKey, final boolean forEncryption,
        final byte[] iv, final byte[] authData) {

    // Initialise AES cipher
    BlockCipher cipher = createAESCipher(secretKey, forEncryption);

    // Create GCM cipher with AES
    GCMBlockCipher gcm = new GCMBlockCipher(cipher);

    AEADParameters aeadParams = new AEADParameters(new KeyParameter(secretKey.getEncoded()),
            AUTH_TAG_BIT_LENGTH, iv, authData);
    gcm.init(forEncryption, aeadParams);

    return gcm;
}

From source file:com.skplanet.jose.jwa.crypto.CryptoUtils.java

License:Open Source License

public static byte[] aesGcmEncrypt(Transformation transformation, byte[] raw, byte[] secret, int atLength,
        byte[] iv, byte[] aad) throws Exception {
    BlockCipher blockCipher = new AESEngine();
    blockCipher.init(true, new KeyParameter(new SecretKeySpec(secret, "AES").getEncoded()));

    GCMBlockCipher aGCMBlockCipher = new GCMBlockCipher(blockCipher);
    aGCMBlockCipher.init(true, new AEADParameters(new KeyParameter(secret), atLength, iv, aad));

    int len = aGCMBlockCipher.getOutputSize(raw.length);
    byte[] out = new byte[len];
    int outOff = aGCMBlockCipher.processBytes(raw, 0, raw.length, out, 0);
    aGCMBlockCipher.doFinal(out, outOff);

    return out;/*w  w w .j ava2 s.com*/
}

From source file:com.skplanet.jose.jwa.crypto.CryptoUtils.java

License:Open Source License

public static byte[] aesGcmDecrypt(Transformation transformation, byte[] encryptedData, byte[] secret,
        int atLength, byte[] iv, byte[] aad) throws Exception {
    BlockCipher blockCipher = new AESEngine();
    blockCipher.init(false, new KeyParameter(new SecretKeySpec(secret, "AES").getEncoded()));

    GCMBlockCipher aGCMBlockCipher = new GCMBlockCipher(blockCipher);
    aGCMBlockCipher.init(false, new AEADParameters(new KeyParameter(secret), atLength, iv, aad));

    int len = aGCMBlockCipher.getOutputSize(encryptedData.length);
    byte[] out = new byte[len];
    int outOff = aGCMBlockCipher.processBytes(encryptedData, 0, encryptedData.length, out, 0);
    aGCMBlockCipher.doFinal(out, outOff);

    return out;/*w  w  w  .j  a v a2 s.com*/
}

From source file:COSE.EncryptCommon.java

private void AES_CCM_Decrypt(AlgorithmID alg, byte[] rgbKey)
        throws CoseException, IllegalStateException, InvalidCipherTextException {
    CCMBlockCipher cipher = new CCMBlockCipher(new AESFastEngine());
    KeyParameter ContentKey;/*from w  w w. ja v a 2s  .c o m*/
    int cbIV = 0;

    switch (alg) {
    case AES_CCM_16_64_128:
    case AES_CCM_16_64_256:
    case AES_CCM_16_128_128:
    case AES_CCM_16_128_256:
        cbIV = 15 - 2;
        break;

    case AES_CCM_64_64_128:
    case AES_CCM_64_64_256:
    case AES_CCM_64_128_256:
    case AES_CCM_64_128_128:
        cbIV = 15 - 8;
        break;
    }

    //  The requirements from JWA

    CBORObject cn = FindAttribute(HeaderKeys.IV);
    if (cn == null)
        throw new CoseException("Missing IV during decryption");
    if (cn.getType() != CBORType.ByteString)
        throw new CoseException("IV is incorrectly formed");
    if (cn.GetByteString().length != cbIV)
        throw new CoseException("IV size is incorrect");

    byte[] IV = cn.GetByteString();

    if (rgbKey.length != alg.getKeySize() / 8)
        throw new CoseException("Missing IV during decryption");
    ContentKey = new KeyParameter(rgbKey);

    //  Build the object to be hashed

    AEADParameters parameters = new AEADParameters(ContentKey, alg.getTagSize(), IV, getAADBytes());

    cipher.init(false, parameters);
    byte[] C = new byte[cipher.getOutputSize(rgbEncrypt.length)];
    int len = cipher.processBytes(rgbEncrypt, 0, rgbEncrypt.length, C, 0);
    len += cipher.doFinal(C, len);

    rgbContent = C;
}