2 * Copyright (c) 2016, 2017 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.aaa.encrypt.impl;
10 import java.nio.charset.Charset;
11 import java.security.InvalidAlgorithmParameterException;
12 import java.security.InvalidKeyException;
13 import java.security.NoSuchAlgorithmException;
14 import java.security.spec.InvalidKeySpecException;
15 import java.security.spec.KeySpec;
16 import java.util.Base64;
17 import javax.crypto.BadPaddingException;
18 import javax.crypto.Cipher;
19 import javax.crypto.IllegalBlockSizeException;
20 import javax.crypto.NoSuchPaddingException;
21 import javax.crypto.SecretKey;
22 import javax.crypto.SecretKeyFactory;
23 import javax.crypto.spec.IvParameterSpec;
24 import javax.crypto.spec.PBEKeySpec;
25 import javax.crypto.spec.SecretKeySpec;
26 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
27 import org.opendaylight.yang.gen.v1.config.aaa.authn.encrypt.service.config.rev160915.EncryptServiceConfig;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
32 * Provides a basic encryption service implementation with configuration knobs.
34 * @author - Sharon Aicler (saichler@gmail.com)
37 public class AAAEncryptionServiceImpl implements AAAEncryptionService {
38 private static final Logger LOG = LoggerFactory.getLogger(AAAEncryptionServiceImpl.class);
40 private final SecretKey key;
41 private final Cipher encryptCipher;
42 private final Cipher decryptCipher;
44 public AAAEncryptionServiceImpl(final EncryptServiceConfig encrySrvConfig) {
45 final byte[] encryptionKeySalt = Base64.getDecoder().decode(encrySrvConfig.requireEncryptSalt());
46 IvParameterSpec tempIvSpec = null;
47 SecretKey tempKey = null;
49 final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(encrySrvConfig.getEncryptMethod());
50 final KeySpec spec = new PBEKeySpec(encrySrvConfig.requireEncryptKey().toCharArray(), encryptionKeySalt,
51 encrySrvConfig.getEncryptIterationCount(), encrySrvConfig.getEncryptKeyLength());
52 tempKey = new SecretKeySpec(keyFactory.generateSecret(spec).getEncoded(), encrySrvConfig.getEncryptType());
53 tempIvSpec = new IvParameterSpec(encryptionKeySalt);
54 } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
55 LOG.error("Failed to initialize secret key", e);
58 final var ivSpec = tempIvSpec;
61 cipher = Cipher.getInstance(encrySrvConfig.getCipherTransforms());
62 cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
63 } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidAlgorithmParameterException
64 | InvalidKeyException e) {
65 LOG.error("Failed to create encrypt cipher.", e);
67 encryptCipher = cipher;
70 cipher = Cipher.getInstance(encrySrvConfig.getCipherTransforms());
71 cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
72 } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidAlgorithmParameterException
73 | InvalidKeyException e) {
74 LOG.error("Failed to create decrypt cipher.", e);
76 decryptCipher = cipher;
80 public String encrypt(final String data) {
81 // We could not instantiate the encryption key, hence no encryption or
82 // decryption will be done.
84 LOG.warn("Encryption Key is NULL, will not encrypt data.");
88 final byte[] cryptobytes;
90 synchronized (encryptCipher) {
91 cryptobytes = encryptCipher.doFinal(data.getBytes(Charset.defaultCharset()));
93 } catch (IllegalBlockSizeException | BadPaddingException e) {
94 LOG.error("Failed to encrypt data.", e);
97 return Base64.getEncoder().encodeToString(cryptobytes);
101 public byte[] encrypt(final byte[] data) {
102 // We could not instantiate the encryption key, hence no encryption or
103 // decryption will be done.
105 LOG.warn("Encryption Key is NULL, will not encrypt data.");
109 synchronized (encryptCipher) {
110 return encryptCipher.doFinal(data);
112 } catch (IllegalBlockSizeException | BadPaddingException e) {
113 LOG.error("Failed to encrypt data.", e);
119 public String decrypt(final String encryptedData) {
120 if (key == null || encryptedData == null || encryptedData.length() == 0) {
121 LOG.warn("String {} was not decrypted.", encryptedData);
122 return encryptedData;
125 final byte[] cryptobytes = Base64.getDecoder().decode(encryptedData);
126 final byte[] clearbytes;
128 clearbytes = decryptCipher.doFinal(cryptobytes);
129 } catch (IllegalBlockSizeException | BadPaddingException e) {
130 LOG.error("Failed to decrypt encoded data", e);
131 return encryptedData;
133 return new String(clearbytes, Charset.defaultCharset());
137 public byte[] decrypt(final byte[] encryptedData) {
138 if (encryptedData == null) {
139 LOG.warn("encryptedData is null.");
140 return encryptedData;
143 return decryptCipher.doFinal(encryptedData);
144 } catch (IllegalBlockSizeException | BadPaddingException e) {
145 LOG.error("Failed to decrypt encoded data", e);
147 return encryptedData;