/** * Unwrap a key by decrypting it with the secret key of the given subject. * The configuration must be set up correctly for key alias resolution. Keys * are always unwrapped using AES. * @param conf configuration * @param subject subject key alias * @param value the encrypted key bytes * @return the raw key bytes * @throws IOException * @throws KeyException */ public static Key unwrapKey(Configuration conf, String subject, byte[] value) throws IOException, KeyException { EncryptionProtos.WrappedKey wrappedKey = EncryptionProtos.WrappedKey.PARSER .parseDelimitedFrom(new ByteArrayInputStream(value)); Cipher cipher = Encryption.getCipher(conf, "AES"); if (cipher == null) { throw new RuntimeException("Algorithm 'AES' not available"); } ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] iv = wrappedKey.hasIv() ? wrappedKey.getIv().toByteArray() : null; Encryption.decryptWithSubjectKey(out, wrappedKey.getData().newInput(), wrappedKey.getLength(), subject, conf, cipher, iv); byte[] keyBytes = out.toByteArray(); if (wrappedKey.hasHash()) { if (!Bytes.equals(wrappedKey.getHash().toByteArray(), Encryption.hash128(keyBytes))) { throw new KeyException("Key was not successfully unwrapped"); } } return new SecretKeySpec(keyBytes, wrappedKey.getAlgorithm()); }
/** * Protect a key by encrypting it with the secret key of the given subject. * The configuration must be set up correctly for key alias resolution. * @param conf configuration * @param subject subject key alias * @param key the key * @return the encrypted key bytes */ public static byte[] wrapKey(Configuration conf, String subject, Key key) throws IOException { // Wrap the key with the configured encryption algorithm. String algorithm = conf.get(HConstants.CRYPTO_KEY_ALGORITHM_CONF_KEY, HConstants.CIPHER_AES); Cipher cipher = Encryption.getCipher(conf, algorithm); if (cipher == null) { throw new RuntimeException("Cipher '" + algorithm + "' not available"); } EncryptionProtos.WrappedKey.Builder builder = EncryptionProtos.WrappedKey.newBuilder(); builder.setAlgorithm(key.getAlgorithm()); byte[] iv = null; if (cipher.getIvLength() > 0) { iv = new byte[cipher.getIvLength()]; RNG.nextBytes(iv); builder.setIv(ByteStringer.wrap(iv)); } byte[] keyBytes = key.getEncoded(); builder.setLength(keyBytes.length); builder.setHash(ByteStringer.wrap(Encryption.hash128(keyBytes))); ByteArrayOutputStream out = new ByteArrayOutputStream(); Encryption.encryptWithSubjectKey(out, new ByteArrayInputStream(keyBytes), subject, conf, cipher, iv); builder.setData(ByteStringer.wrap(out.toByteArray())); // Build and return the protobuf message out.reset(); builder.build().writeDelimitedTo(out); return out.toByteArray(); }
/** * Unwrap a key by decrypting it with the secret key of the given subject. * The configuration must be set up correctly for key alias resolution. * @param conf configuration * @param subject subject key alias * @param value the encrypted key bytes * @return the raw key bytes * @throws IOException * @throws KeyException */ public static Key unwrapKey(Configuration conf, String subject, byte[] value) throws IOException, KeyException { EncryptionProtos.WrappedKey wrappedKey = EncryptionProtos.WrappedKey.PARSER .parseDelimitedFrom(new ByteArrayInputStream(value)); String algorithm = conf.get(HConstants.CRYPTO_KEY_ALGORITHM_CONF_KEY, HConstants.CIPHER_AES); Cipher cipher = Encryption.getCipher(conf, algorithm); if (cipher == null) { throw new RuntimeException("Cipher '" + algorithm + "' not available"); } return getUnwrapKey(conf, subject, wrappedKey, cipher); }
private static Key getUnwrapKey(Configuration conf, String subject, EncryptionProtos.WrappedKey wrappedKey, Cipher cipher) throws IOException, KeyException { ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] iv = wrappedKey.hasIv() ? wrappedKey.getIv().toByteArray() : null; Encryption.decryptWithSubjectKey(out, wrappedKey.getData().newInput(), wrappedKey.getLength(), subject, conf, cipher, iv); byte[] keyBytes = out.toByteArray(); if (wrappedKey.hasHash()) { if (!Bytes.equals(wrappedKey.getHash().toByteArray(), Encryption.hash128(keyBytes))) { throw new KeyException("Key was not successfully unwrapped"); } } return new SecretKeySpec(keyBytes, wrappedKey.getAlgorithm()); }
/** * Unwrap a wal key by decrypting it with the secret key of the given subject. The configuration * must be set up correctly for key alias resolution. * @param conf configuration * @param subject subject key alias * @param value the encrypted key bytes * @return the raw key bytes * @throws IOException if key is not found for the subject, or if some I/O error occurs * @throws KeyException if fail to unwrap the key */ public static Key unwrapWALKey(Configuration conf, String subject, byte[] value) throws IOException, KeyException { EncryptionProtos.WrappedKey wrappedKey = EncryptionProtos.WrappedKey.PARSER.parseDelimitedFrom(new ByteArrayInputStream(value)); String algorithm = conf.get(HConstants.CRYPTO_WAL_ALGORITHM_CONF_KEY, HConstants.CIPHER_AES); Cipher cipher = Encryption.getCipher(conf, algorithm); if (cipher == null) { throw new RuntimeException("Cipher '" + algorithm + "' not available"); } return getUnwrapKey(conf, subject, wrappedKey, cipher); }
/** * Protect a key by encrypting it with the secret key of the given subject. * The configuration must be set up correctly for key alias resolution. Keys * are always wrapped using AES. * @param conf configuration * @param subject subject key alias * @param key the key * @return the encrypted key bytes */ public static byte[] wrapKey(Configuration conf, String subject, Key key) throws IOException { // Wrap the key with AES Cipher cipher = Encryption.getCipher(conf, "AES"); if (cipher == null) { throw new RuntimeException("Cipher 'AES' not available"); } EncryptionProtos.WrappedKey.Builder builder = EncryptionProtos.WrappedKey.newBuilder(); builder.setAlgorithm(key.getAlgorithm()); byte[] iv = null; if (cipher.getIvLength() > 0) { iv = new byte[cipher.getIvLength()]; RNG.nextBytes(iv); builder.setIv(ByteStringer.wrap(iv)); } byte[] keyBytes = key.getEncoded(); builder.setLength(keyBytes.length); builder.setHash(ByteStringer.wrap(Encryption.hash128(keyBytes))); ByteArrayOutputStream out = new ByteArrayOutputStream(); Encryption.encryptWithSubjectKey(out, new ByteArrayInputStream(keyBytes), subject, conf, cipher, iv); builder.setData(ByteStringer.wrap(out.toByteArray())); // Build and return the protobuf message out.reset(); builder.build().writeDelimitedTo(out); return out.toByteArray(); }
/** * Protect a key by encrypting it with the secret key of the given subject. * The configuration must be set up correctly for key alias resolution. Keys * are always wrapped using AES. * @param conf configuration * @param subject subject key alias * @param key the key * @return the encrypted key bytes */ public static byte[] wrapKey(Configuration conf, String subject, Key key) throws IOException { // Wrap the key with AES Cipher cipher = Encryption.getCipher(conf, "AES"); if (cipher == null) { throw new RuntimeException("Cipher 'AES' not available"); } EncryptionProtos.WrappedKey.Builder builder = EncryptionProtos.WrappedKey.newBuilder(); builder.setAlgorithm(key.getAlgorithm()); byte[] iv = null; if (cipher.getIvLength() > 0) { iv = new byte[cipher.getIvLength()]; RNG.nextBytes(iv); builder.setIv(HBaseZeroCopyByteString.wrap(iv)); } byte[] keyBytes = key.getEncoded(); builder.setLength(keyBytes.length); builder.setHash(HBaseZeroCopyByteString.wrap(Encryption.hash128(keyBytes))); ByteArrayOutputStream out = new ByteArrayOutputStream(); Encryption.encryptWithSubjectKey(out, new ByteArrayInputStream(keyBytes), subject, conf, cipher, iv); builder.setData(HBaseZeroCopyByteString.wrap(out.toByteArray())); // Build and return the protobuf message out.reset(); builder.build().writeDelimitedTo(out); return out.toByteArray(); }