001package org.intellimate.izou.security; 002 003import org.apache.logging.log4j.LogManager; 004import org.apache.logging.log4j.Logger; 005import org.bouncycastle.jcajce.provider.digest.SHA3; 006import org.bouncycastle.util.encoders.Hex; 007 008import javax.crypto.*; 009import java.io.UnsupportedEncodingException; 010import java.security.InvalidKeyException; 011import java.security.NoSuchAlgorithmException; 012import java.security.NoSuchProviderException; 013import java.security.Security; 014 015/** 016 * SecurityFunction implements basic cryptographic functions like hash functions or encryption and decryption 017 * functions. 018 */ 019public final class SecurityFunctions { 020 private final Logger logger = LogManager.getLogger(this.getClass()); 021 022 /** 023 * Applies SHA-3 hash function on the {@code input} string 024 * 025 * @param input the string to apply to SHA-3 hash on 026 * @return the hashed input string 027 */ 028 public String sha3(String input) { 029 String hash = ""; 030 try { 031 SHA3.DigestSHA3 md = new SHA3.DigestSHA3(256); 032 md.update(input.getBytes("UTF-8")); 033 hash = Hex.toHexString(md.digest()); 034 } catch (UnsupportedEncodingException e) { 035 logger.error("Error while hashing with SHA-3", e); 036 } 037 038 return hash; 039 } 040 041 /** 042 * Applies an AES encryption on the string {@code plainText} with they given key 043 * <p> 044 * Keys have to be generated using the {@link #generateKey()} function 045 * </p> 046 * @param plainText the string to encrypt 047 * @param key the key to use during the encryption 048 * @return a byte array containing the encrypted data 049 */ 050 public byte[] encryptAES(String plainText, SecretKey key) { 051 byte[] byteCipherText = new byte[0]; 052 053 try { 054 Cipher cipher = Cipher.getInstance("AES", "BC"); 055 cipher.init(Cipher.ENCRYPT_MODE, key); 056 byteCipherText = cipher.doFinal(plainText.getBytes("UTF-8")); 057 } catch (BadPaddingException | NoSuchAlgorithmException | IllegalBlockSizeException | NoSuchPaddingException 058 | InvalidKeyException | UnsupportedEncodingException | NoSuchProviderException e) { 059 logger.error("Unable to apply AES encryption", e); 060 } 061 062 return byteCipherText; 063 } 064 065 /** 066 * Applies an AES decryption on the byte array {@code cipherBytes} with they given key. The key has to be the same 067 * key used during encryption, else null is returned 068 * 069 * @param cipherBytes the byte array to decrypt 070 * @param key the key to use during the decryption 071 * @return the decrypted string if everything was successful, else null 072 */ 073 public String decryptAES(byte[] cipherBytes, SecretKey key) { 074 String plainText = null; 075 Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); 076 try { 077 Cipher cipher = Cipher.getInstance("AES", "BC"); 078 cipher.init(Cipher.DECRYPT_MODE, key); 079 byte[] bytePlainText = cipher.doFinal(cipherBytes); 080 plainText = new String(bytePlainText, "UTF-8"); 081 } catch (IllegalBlockSizeException | InvalidKeyException | NoSuchAlgorithmException | BadPaddingException 082 | NoSuchPaddingException | UnsupportedEncodingException | NoSuchProviderException e) { 083 logger.error("Unable to apply AES decryption", e); 084 } 085 086 return plainText; 087 } 088 089 /** 090 * Generates a key for the AES encryption 091 * 092 * @return a new key for the AES encryption 093 */ 094 public SecretKey generateKey() { 095 SecretKey key = null; 096 try { 097 KeyGenerator generator = KeyGenerator.getInstance("AES"); 098 generator.init(128); 099 key = generator.generateKey(); 100 } catch (NoSuchAlgorithmException e) { 101 logger.error("Unable to generate AES key", e); 102 } 103 104 return key; 105 } 106}