blob: c691937c2b1250b736c982d7c8d5509f738d929e [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <string>
#include <vector>
namespace org {
namespace apache {
namespace nifi {
namespace minifi {
namespace utils {
namespace crypto {
using Bytes = std::vector<unsigned char>;
Bytes stringToBytes(const std::string& text);
std::string bytesToString(const Bytes& bytes);
Bytes generateKey();
Bytes randomBytes(size_t num_bytes);
struct EncryptionType {
static std::string name();
static size_t keyLength();
static size_t nonceLength();
static size_t macLength();
static std::string separator();
};
/**
* Encrypt the input (raw version).
*
* Uses libsodium's secretbox encryption.
* Takes the plaintext as input, and returns the ciphertext (encrypted plaintext) plus the MAC (message authentication
* code), in binary form.
* The ciphertext has the same length as the plaintext, and the MAC is always EncryptionType::macLength() bytes long,
* so the output is EncryptionType::macLength() bytes longer than the input.
*
* @param plaintext plaintext
* @param key secret key of EncryptionType::keyLength() bytes, should be generated by a CSPRNG
* @param nonce random data freshly generated for each encryption to break rainbow table-type attacks;
* not encrypted and not secret, but included when computing the ciphertext;
* the length is EncryptionType::nonceLength() bytes, should be generated by a CSPRNG
* @return ciphertext plus MAC
* @throws std::exception if the input is incorrect (wrong lengths)
*/
Bytes encryptRaw(const Bytes& plaintext, const Bytes& key, const Bytes& nonce);
/**
* Encrypt the plaintext using a randomly-generated nonce.
*
* * Generates a random nonce,
* * calls encryptRaw(),
* * base64-encodes the nonce and the ciphertext-plus-MAC, and
* * returns <encoded nonce><EncryptionType::separator()><encoded ciphertext-plus-MAC>.
*/
std::string encrypt(const std::string& plaintext, const Bytes& key);
/**
* Decrypt the input (raw version).
*
* Uses libsodium's secretbox decryption.
* Takes the (binary) ciphertext plus MAC as input, and returns the plaintext. It also authenticates the input by
* checking the MAC.
* The plaintext has the same length as the ciphertext, and the MAC is always EncryptionType::macLength() bytes long,
* so the output is EncryptionType::macLength() bytes shorter than the input.
*
* @param input ciphertext plus MAC
* @param key secret key of EncryptionType::keyLength() bytes, must be the same as used when encrypting
* @param nonce random data freshly generated for each encryption to break rainbow table-type attacks;
* EncryptionType::nonceLength() bytes, must be the same as used when encrypting
* @return plaintext
* @throws std::exception if either the decryption or the authentication fails
*/
Bytes decryptRaw(const Bytes& input, const Bytes& key, const Bytes& nonce);
/**
* Decrypt an input of the form nonce + EncryptionType::separator() + ciphertext_plus_MAC.
*
* * Splits the input at EncryptionType::separator(),
* * base64-decodes the two parts of the input (nonce and ciphertext-plus-MAC),
* * calls deryptRaw(),
* * returns the decrypted plaintext.
*/
std::string decrypt(const std::string& input, const Bytes& key);
} // namespace crypto
} // namespace utils
} // namespace minifi
} // namespace nifi
} // namespace apache
} // namespace org