/** * Encrypts or decrypts the given input. * * @param in input * @param s encryption type * @param k secret key * @param a encryption algorithm * @param ec encrypt or decrypt * @return encrypted or decrypted input * @throws QueryException query exception */ Str encryption(final byte[] in, final byte[] s, final byte[] k, final byte[] a, final boolean ec) throws QueryException { final boolean symmetric = eq(lc(s), SYM) || s.length == 0; final byte[] aa = a.length == 0 ? DES : a; final byte[] tivl = ALGE.get(lc(aa)); if (!symmetric) throw CX_ENCTYP.get(info, ec); if (tivl == null) throw CX_INVALGO.get(info, s); // initialization vector length final int ivl = toInt(tivl); try { return Str.get(ec ? encrypt(in, k, aa, ivl) : decrypt(in, k, aa, ivl)); } catch (final NoSuchPaddingException e) { throw CX_NOPAD.get(info, e); } catch (final BadPaddingException e) { throw CX_BADPAD.get(info, e); } catch (final InvalidKeyException e) { throw CX_KEYINV.get(info, e); } catch (final IllegalBlockSizeException e) { throw CX_ILLBLO.get(info, e); } catch (final GeneralSecurityException e) { throw CX_INVALGO.get(info, e); } }
/** * Decrypts the given input data. * * @param in data to decrypt * @param k secret key * @param a encryption algorithm * @param ivl initialization vector length * @return decrypted data * @throws NoSuchAlgorithmException ex * @throws NoSuchPaddingException ex * @throws InvalidKeyException ex * @throws InvalidAlgorithmParameterException ex * @throws IllegalBlockSizeException ex * @throws BadPaddingException ex */ private static byte[] decrypt(final byte[] in, final byte[] k, final byte[] a, final int ivl) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException { final SecretKeySpec keySpec = new SecretKeySpec(k, string(a)); final Cipher cipher = Cipher.getInstance(string(ALGN.get(lc(a)))); // extract iv from message beginning final byte[] iv = substring(in, 0, ivl); final IvParameterSpec ivspec = new IvParameterSpec(iv); cipher.init(Cipher.DECRYPT_MODE, keySpec, ivspec); return cipher.doFinal(substring(in, ivl, in.length)); }
/** * Encrypts the given input data. * * @param in input data to encrypt * @param k key * @param a encryption algorithm * @param ivl initialization vector length * @return encrypted input data * @throws InvalidKeyException ex * @throws InvalidAlgorithmParameterException ex * @throws NoSuchAlgorithmException ex * @throws NoSuchPaddingException ex * @throws IllegalBlockSizeException ex * @throws BadPaddingException ex */ private static byte[] encrypt(final byte[] in, final byte[] k, final byte[] a, final int ivl) throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { final Cipher cipher = Cipher.getInstance(string(ALGN.get(lc(a)))); final SecretKeySpec kspec = new SecretKeySpec(k, string(a)); // generate random iv. random iv is necessary to make the encryption of a // string look different every time it is encrypted. final byte[] iv = new byte[ivl]; // create new random iv if encrypting final SecureRandom rand = SecureRandom.getInstance("SHA1PRNG"); rand.nextBytes(iv); final IvParameterSpec ivspec = new IvParameterSpec(iv); // encrypt/decrypt cipher.init(Cipher.ENCRYPT_MODE, kspec, ivspec); final byte[] t = cipher.doFinal(in); // initialization vector is appended to the message for later decryption return concat(iv, t); }
/** * Creates a message authentication code (MAC) for the given input. * * @param msg input * @param k secret key * @param a encryption algorithm * @param enc encoding * @return MAC * @throws QueryException query exception */ Item hmac(final byte[] msg, final byte[] k, final byte[] a, final byte[] enc) throws QueryException { // create hash value from input message final Key key = new SecretKeySpec(k, string(a)); final byte[] aa = a.length == 0 ? DEFA : a; if (!ALGHMAC.contains(lc(aa))) throw CX_INVHASH.get(info, aa); final boolean b64 = eq(lc(enc), BASE64) || enc.length == 0; if (!b64 && !eq(lc(enc), HEX)) throw CX_ENC.get(info, enc); try { final Mac mac = Mac.getInstance(string(ALGHMAC.get(lc(aa)))); mac.init(key); final byte[] hash = mac.doFinal(msg); // convert to specified encoding, base64 as a standard, else use hex return Str.get(b64 ? org.basex.util.Base64.encode(hash) : hex(hash, true)); } catch (final NoSuchAlgorithmException e) { throw CX_INVHASH.get(info, e); } catch (final InvalidKeyException e) { throw CX_KEYINV.get(info, e); } }
/** * Constructor. * * @param info input info * @param map decimal format * @throws QueryException query exception */ public DecFormatter(final InputInfo info, final TokenMap map) throws QueryException { // assign map values int z = '0'; if (map != null) { for (final byte[] key : map) { final String k = string(key); final byte[] v = map.get(key); if (k.equals(DF_INF)) { inf = v; } else if (k.equals(DF_NAN)) { nan = v; } else if (v.length != 0 && cl(v, 0) == v.length) { final int cp = cp(v, 0); switch (k) { case DF_DEC: decimal = cp; break; case DF_GRP: grouping = cp; break; case DF_EXP: exponent = cp; break; case DF_PAT: pattern = cp; break; case DF_MIN: minus = cp; break; case DF_DIG: optional = cp; break; case DF_PC: percent = cp; break; case DF_PM: permille = cp; break; case DF_ZD: z = zeroes(cp); if (z == -1) throw INVDECFORM_X_X.get(info, k, v); if (z != cp) throw INVDECZERO_X.get(info, (char) cp); break; } } else { // signs must have single character throw INVDECSINGLE_X_X.get(info, k, v); } } } // check for duplicate characters zero = z; final IntSet is = new IntSet(); for (int i = 0; i < 10; i++) is.add(zero + i); final int[] ss = {decimal, grouping, exponent, percent, permille, optional, pattern}; for (final int s : ss) if (!is.add(s)) throw DUPLDECFORM_X.get(info, (char) s); // create auxiliary strings final TokenBuilder tb = new TokenBuilder(); for (int i = 0; i < 10; i++) tb.add(zero + i); digits = tb.toArray(); // "decimal-separator-sign, exponent-separator-sign, grouping-sign, decimal-digit-family, // optional-digit-sign and pattern-separator-sign are classified as active characters" // -> decimal-digit-family: added above. pattern-separator-sign: will never occur at this stage actives = tb.add(decimal).add(exponent).add(grouping).add(optional).finish(); // "all other characters (including the percent-sign and per-mille-sign) are classified // as passive characters." }