List of usage examples for org.bouncycastle.crypto.params AEADParameters AEADParameters
public AEADParameters(KeyParameter key, int macSize, byte[] nonce, byte[] associatedText)
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; }