/** * Copyright (c) 2006-2014 The Sakai Foundation * * Licensed under the Educational Community 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.opensource.org/licenses/ECL-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. * * This code was adapted from Chuck Hedreick's Linktool utlity code */ package org.sakaiproject.basiclti.util; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; //import org.sakaiproject.component.cover.ServerConfigurationService; /** * Support Blowfish Encryption and Decryption */ public class BlowFish { // Default JCE only supports 128 bit encryption public static final int MAX_KEY_LENGTH = 128 / 8; private static char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; /** * Strengthen a key which might be too short by extending with a salt text * * @param secret * String * @param salt * String * @throws Exception. */ public static String strengthenKey(String secret, String salt ) { if ( secret.length() > BlowFish.MAX_KEY_LENGTH ) return secret; // Extend the secret to the maximum Blowfish length secret = secret + salt; return secret.substring(0, BlowFish.MAX_KEY_LENGTH); } /** * Decrypt a string using Blowfish * * @param secret * A hex-encoded secret - secrets longer than the maximum key length will be truncated * @param str * The plain text to be encoded */ public static String encrypt(String secret, String str) { if ( secret == null ) return null; if ( secret.length() > MAX_KEY_LENGTH*2 ) { secret = secret.substring(0,MAX_KEY_LENGTH*2); } try { byte[] secretBytes = PortableShaUtil.hex2bin(secret); SecretKey secretKey = new SecretKeySpec(secretBytes, "Blowfish"); Cipher ecipher = Cipher.getInstance("Blowfish"); ecipher.init(Cipher.ENCRYPT_MODE, secretKey); // Encode the string into bytes using utf-8 byte[] utf8 = str.getBytes("UTF8"); // Encrypt byte[] enc = ecipher.doFinal(utf8); // Encode bytes to base64 to get a string return PortableShaUtil.bin2hex(enc); } catch (javax.crypto.BadPaddingException e) { throw new Error(e); } catch (javax.crypto.IllegalBlockSizeException e) { throw new Error(e); } catch (java.security.NoSuchAlgorithmException e) { throw new Error(e); } catch (java.security.InvalidKeyException e) { throw new Error(e); } catch (javax.crypto.NoSuchPaddingException e) { throw new Error(e); } catch (java.io.UnsupportedEncodingException e) { throw new Error(e); } } /** * Decrypt a string using Blowfish * * @param secret * A hex-encoded secret - secrets longer than the maximum key length will be truncated * @param enc * A hex-encoded ciphertext */ public static String decrypt (String secret, String enc) { if ( secret == null ) return null; if ( secret.length() > MAX_KEY_LENGTH*2 ) { secret = secret.substring(0,MAX_KEY_LENGTH*2); } try { byte [] secretBytes = PortableShaUtil.hex2bin(secret); SecretKey secretKey = new SecretKeySpec(secretBytes, "Blowfish"); Cipher dcipher = Cipher.getInstance("Blowfish"); dcipher.init(Cipher.DECRYPT_MODE, secretKey); byte[] dec = PortableShaUtil.hex2bin(enc); // Decrypt byte[] utf8 = dcipher.doFinal(dec); // Decode using utf-8 return new String(utf8, "UTF8"); } catch (Exception e) { throw new Error(e); } } }