Package org.jmanage.core.crypto

Source Code of org.jmanage.core.crypto.Crypto

/**
* Copyright 2004-2005 jManage.org
*
* Licensed 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.
*/
package org.jmanage.core.crypto;

import org.jmanage.core.util.Loggers;
import org.jmanage.core.util.JManageProperties;

import javax.crypto.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Logger;

/**
* Crypto acts as a facade layer for the crypto classes.
*
* Note that the crypto functions must not be called directly from CLI. This
* is because server has the crypto keys and the crypto configuration.
*
* date:  Jul 23, 2004
* @author  Rakesh Kalra
*/
public class Crypto {

    private static final Logger logger = Loggers.getLogger(Crypto.class);

    /* get the hashing algorithm from jmanage.properties */
    private static final String hashAlgorithm =
            JManageProperties.getHashAlgorithm();

    private static Cipher encrypter;
    private static Cipher decrypter;

    public static void init(char[] password){
        EncryptedKey encryptedKey = KeyManager.readKey(password);
        SecretKey secretKey = encryptedKey.getSecretKey();
        encrypter = getCipher(Cipher.ENCRYPT_MODE, secretKey);
        assert encrypter != null;
        decrypter = getCipher(Cipher.DECRYPT_MODE, secretKey);
        assert decrypter != null;
        logger.info("Crypto initialized");
    }

    public static synchronized byte[] encrypt(String plaintext){
        try {
            return encrypter.doFinal(plaintext.getBytes());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String encryptToString(String plaintext){
        byte[] ciphertext = encrypt(plaintext);
        return byteArrayToHexString(ciphertext);
    }

    public static synchronized byte[] decrypt(byte[] ciphertext){
        try {
            return decrypter.doFinal(ciphertext);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String decrypt(String ciphertext){
        byte[] plaintext = decrypt(hexStringToByteArray(ciphertext));
        return new String(plaintext);
    }

    /**
     * hash method can be used without calling init() method on Crypto.
     *
     * @param plaintext
     * @return
     */
    public static String hash(String plaintext){
        return hash(plaintext.toCharArray());
    }

    public static String hash(char[] plaintext){
        try {
            MessageDigest sha = MessageDigest.getInstance(hashAlgorithm);
            byte[] hash = sha.digest(charArrayToByteArray(plaintext));
            return byteArrayToHexString(hash);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    private static Cipher getCipher(int mode, SecretKey secretKey){

        try {
            Cipher cipher = Cipher.getInstance(EncryptedKey.CRYPTO_ALGORITHM);
            cipher.init(mode, secretKey);
            return cipher;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static byte[] charArrayToByteArray(char[] array){
        final byte[] output = new byte[array.length];
        for(int i=0; i<output.length; i++){
            output[i] = (byte) array[i];
        }
        return output;
    }

    private static String byteArrayToHexString(byte[] ba)
    {
        StringBuffer buffer = new StringBuffer(ba.length * 2);
        int n = ba.length;
        for (int i = 0; i < n; i++) {
            byte b = ba[i];
            appendASCII(b, buffer);
        }
        return buffer.toString();
    }

    private static byte[] hexStringToByteArray(String s) {
        char[] ca = s.toCharArray();
        int n_chars = ca.length;
        byte[] ba = new byte[n_chars / 2];
        int ci = 0;
        int bi = 0;
        while (ci < n_chars) {
            char c = ca[ci++];
            byte hi = hexCharToByte(c);
            c = ca[ci++];
            byte lo = hexCharToByte(c);
            ba[bi++] = (byte) ((hi << 4) | lo);
        }
        return ba;
    }

    private static void appendASCII(byte b, StringBuffer buffer) {
        byte hi = (byte) ((b >> 4) & 0xf);
        byte lo = (byte) (b & 0xf);
        buffer.append(hexByteToChar(hi));
        buffer.append(hexByteToChar(lo));
    }

    private static char hexByteToChar(byte b) {
        char c = 0;
        switch (b)
        {
        case 0x0: c = '0'; break;
        case 0x1: c = '1'; break;
        case 0x2: c = '2'; break;
        case 0x3: c = '3'; break;
        case 0x4: c = '4'; break;
        case 0x5: c = '5'; break;
        case 0x6: c = '6'; break;
        case 0x7: c = '7'; break;
        case 0x8: c = '8'; break;
        case 0x9: c = '9'; break;
        case 0xa: c = 'a'; break;
        case 0xb: c = 'b'; break;
        case 0xc: c = 'c'; break;
        case 0xd: c = 'd'; break;
        case 0xe: c = 'e'; break;
        case 0xf: c = 'f'; break;
        default: assert false:"Bad byte digit of '" + c + "' received"; break;
        }
        return c;
    }

    private static byte hexCharToByte(char c) {
        byte b = 0;
        switch (c)
        {
        case '0': b = 0x0; break;
        case '1': b = 0x1; break;
        case '2': b = 0x2; break;
        case '3': b = 0x3; break;
        case '4': b = 0x4; break;
        case '5': b = 0x5; break;
        case '6': b = 0x6; break;
        case '7': b = 0x7; break;
        case '8': b = 0x8; break;
        case '9': b = 0x9; break;
        case 'a': case 'A': b = 0xa; break;
        case 'b': case 'B': b = 0xb; break;
        case 'c': case 'C': b = 0xc; break;
        case 'd': case 'D': b = 0xd; break;
        case 'e': case 'E': b = 0xe; break;
        case 'f': case 'F': b = 0xf; break;
        default: assert false:"Bad hex digit of '" + c + "' received"; break;
        }
        return b;
    }
}
TOP

Related Classes of org.jmanage.core.crypto.Crypto

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.