Package org.platformlayer.crypto

Source Code of org.platformlayer.crypto.CryptoUtils$HashAndLength

package org.platformlayer.crypto;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import com.fathomdb.hash.Md5Hash;
import com.fathomdb.hash.Sha1Hash;
import com.fathomdb.io.ByteSource;
import com.fathomdb.io.IoUtils;

public class CryptoUtils {
  private static final String UTF8 = "UTF-8";
  // private static final String ALGORITHM_3DES = "DES/ECB/PKCS5Padding";
  private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
  private static final String HMAC_SHA256_ALGORITHM = "HmacSHA256";
  private static final String SHA1_ALGORITHM = "SHA-1";
  private static final String SHA256_ALGORITHM = "SHA-256";

  public static final int HMAC_SHA1_BYTES = 160 / 8;
  public static final int HMAC_SHA256_BYTES = 256 / 8;

  static final SecureRandom SECURE_RANDOM = new SecureRandom();

  public static String fromBytesUtf8(byte[] bytes) {
    try {
      return new String(bytes, UTF8);
    } catch (UnsupportedEncodingException e) {
      throw new IllegalStateException("Error decoding utf-8 bytes", e);
    }
  }

  public static Sha1Hash sha1(ByteSource byteSource) throws IOException {
    InputStream is = byteSource.open();
    try {
      return sha1(is);
    } finally {
      IoUtils.safeClose(is);
    }
  }

  public static Sha1Hash sha1(byte[] plainText) {
    MessageDigest digest = getThreadLocalSha1();

    byte[] hash = digest.digest(plainText);
    return new Sha1Hash(hash);
  }

  public static Sha1Hash sha1(String a) {
    MessageDigest digest = getThreadLocalSha1();

    byte[] hash = digest.digest(toBytesUtf8(a));
    return new Sha1Hash(hash);
  }

  public static Md5Hash md5(String a) {
    return md5(toBytesUtf8(a));
  }

  public static Md5Hash md5(byte[] data) {
    MessageDigest digest = buildMd5();

    byte[] hash = digest.digest(data);
    return new Md5Hash(hash);
  }

  public static Md5Hash md5(byte[] b1, byte[] b2) {
    MessageDigest digest = buildMd5();

    digest.update(b1);
    byte[] hash = digest.digest(b2);
    return new Md5Hash(hash);
  }

  public static Md5Hash md5(byte[] b1, byte[] b2, byte[] b3) {
    MessageDigest digest = buildMd5();

    digest.update(b1);
    digest.update(b2);
    byte[] hash = digest.digest(b3);
    return new Md5Hash(hash);
  }

  public static Sha1Hash sha1(byte[] buffer1, byte[] buffer2) {
    MessageDigest digest = getThreadLocalSha1();

    digest.update(buffer1);
    byte[] hash = digest.digest(buffer2);
    return new Sha1Hash(hash);
  }

  public static Sha1Hash sha1(String a, String b) {
    MessageDigest digest = getThreadLocalSha1();

    digest.update(toBytesUtf8(a));
    byte[] hash = digest.digest(toBytesUtf8(b));
    return new Sha1Hash(hash);
  }

  public static Sha1Hash sha1(String... data) {
    MessageDigest digest = getThreadLocalSha1();

    for (int i = 0; i < data.length - 1; i++) {
      digest.update(toBytesUtf8(data[i]));
    }

    byte[] hash = digest.digest(toBytesUtf8(data[data.length - 1]));
    return new Sha1Hash(hash);
  }

  public static Sha1Hash sha1(byte[] a, byte[] b, byte[] c) {
    MessageDigest digest = getThreadLocalSha1();

    digest.update(a);
    digest.update(b);
    byte[] hash = digest.digest(c);
    return new Sha1Hash(hash);
  }

  public static Sha1Hash sha1(byte[]... data) {
    MessageDigest digest = getThreadLocalSha1();

    for (int i = 0; i < data.length - 1; i++) {
      digest.update(data[i]);
    }

    byte[] hash = digest.digest(data[data.length - 1]);
    return new Sha1Hash(hash);
  }

  public static Sha256Hash sha256(byte[]... data) {
    MessageDigest digest = getSha256();

    for (int i = 0; i < data.length - 1; i++) {
      digest.update(data[i]);
    }

    byte[] hash = digest.digest(data[data.length - 1]);
    return new Sha256Hash(hash);
  }

  public static Mac buildHmacSha1(SecretKey key) {
    Mac mac = getHmacSha1();
    try {
      mac.init(key);
    } catch (InvalidKeyException e) {
      throw new IllegalStateException("Unexpected encryption error", e);
    }
    return mac;
  }

  public static Mac buildHmacSha256(SecretKey key) {
    Mac mac = getHmacSha256();
    try {
      mac.init(key);
    } catch (InvalidKeyException e) {
      throw new IllegalStateException("Unexpected encryption error", e);
    }
    return mac;
  }

  public static SecretKeySpec buildHmacSha1Key(byte[] keyData) {
    SecretKeySpec signingKey = new SecretKeySpec(keyData, HMAC_SHA1_ALGORITHM);
    return signingKey;
  }

  public static SecretKeySpec buildHmacSha256Key(byte[] keyData) {
    SecretKeySpec signingKey = new SecretKeySpec(keyData, HMAC_SHA256_ALGORITHM);
    return signingKey;
  }

  public static byte[] hmacSha1(SecretKeySpec signingKey, byte[]... data) {
    Mac mac = buildHmacSha1(signingKey);

    return computeMac(mac, data);
  }

  public static byte[] hmacSha256(SecretKeySpec signingKey, byte[]... data) {
    Mac mac = buildHmacSha256(signingKey);

    return computeMac(mac, data);
  }

  public static byte[] computeMac(Mac mac, byte[]... data) {
    for (int i = 0; i < data.length - 1; i++) {
      mac.update(data[i]);
    }

    byte[] hash = mac.doFinal(data[data.length - 1]);
    return hash;
  }

  public static byte[] hmacSha1(SecretKeySpec signingKey, byte[] buffer, int offset, int length) {
    Mac mac = buildHmacSha1(signingKey);

    mac.update(buffer, offset, length);
    byte[] hash = mac.doFinal();
    return hash;
  }

  private static MessageDigest getMessageDigest(String algorithm) {
    try {
      MessageDigest digest = MessageDigest.getInstance(algorithm);
      return digest;
    } catch (NoSuchAlgorithmException e) {
      // should not happen
      throw new IllegalStateException("Could not find MessageDigest algorithm: " + algorithm, e);
    }
  }

  private static Mac getMac(String algorithm) {
    try {
      Mac digest = Mac.getInstance(algorithm);
      return digest;
    } catch (NoSuchAlgorithmException e) {
      // should not happen
      throw new IllegalStateException("Could not find Mac algorithm: " + algorithm, e);
    }
  }

  static final boolean USE_THREAD_LOCAL_SHA1 = false;
  static final ThreadLocal<MessageDigest> THREAD_LOCAL_SHA1 = new ThreadLocal<MessageDigest>();

  private static MessageDigest getThreadLocalSha1() {
    if (USE_THREAD_LOCAL_SHA1) {
      MessageDigest messageDigest = THREAD_LOCAL_SHA1.get();
      if (messageDigest == null) {
        messageDigest = getSha1();
        THREAD_LOCAL_SHA1.set(messageDigest);
      } else {
        messageDigest.reset();
      }
      return messageDigest;
    } else {
      return getSha1();
    }
  }

  public static MessageDigest getSha1() {
    return getMessageDigest(SHA1_ALGORITHM);
  }

  public static MessageDigest getSha256() {
    return getMessageDigest(SHA256_ALGORITHM);
  }

  private static Mac getHmacSha1() {
    return getMac(HMAC_SHA1_ALGORITHM);
  }

  private static Mac getHmacSha256() {
    return getMac(HMAC_SHA256_ALGORITHM);
  }

  // public static byte[] decrypt3Des(byte[] key, byte[] cipherText) throws CryptoException {
  // try {
  // KeySpec ks = new DESKeySpec(key);
  // SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
  // SecretKey secret = keyFactory.generateSecret(ks);
  // Cipher cipher = Cipher.getInstance(ALGORITHM_3DES);
  // cipher.init(Cipher.DECRYPT_MODE, secret);
  // byte[] plainText = cipher.doFinal(cipherText);
  // return plainText;
  // } catch (Exception e) {
  // if (e instanceof InterruptedException) {
  // Thread.currentThread().interrupt();
  // }
  // throw new CryptoException("Error while decrypting data", e);
  // }
  // }
  //
  // public static byte[] encrypt3Des(byte[] key, byte[] plainText) throws CryptoException {
  // try {
  // KeySpec ks = new DESKeySpec(key);
  // SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
  // SecretKey secret = keyFactory.generateSecret(ks);
  // Cipher cipher = Cipher.getInstance(ALGORITHM_3DES);
  // cipher.init(Cipher.ENCRYPT_MODE, secret);
  // byte[] cipherText = cipher.doFinal(plainText);
  // return cipherText;
  // } catch (Exception e) {
  // if (e instanceof InterruptedException) {
  // Thread.currentThread().interrupt();
  // }
  // throw new CryptoException("Error while decrypting data", e);
  // }
  // }

  public static byte[] toBytesUtf8(String s) {
    try {
      return s.getBytes(UTF8);
    } catch (UnsupportedEncodingException e) {
      throw new IllegalStateException("Error getting utf-8 bytes", e);
    }
  }

  public static String toStringUtf8(byte[] bytes) {
    try {
      return new String(bytes, UTF8);
    } catch (UnsupportedEncodingException e) {
      throw new IllegalStateException("Error reading utf-8 bytes", e);
    }
  }

  public static Sha1Hash sha1(InputStream inputStream) throws IOException {
    MessageDigest digest = getThreadLocalSha1();
    return new Sha1Hash(hash(digest, inputStream).hash);
  }

  public static Md5Hash md5(InputStream inputStream) throws IOException {
    MessageDigest digest = buildMd5();
    return new Md5Hash(hash(digest, inputStream).hash);
  }

  static class HashAndLength {
    final byte[] hash;
    final long length;

    HashAndLength(byte[] hash, long length) {
      this.hash = hash;
      this.length = length;
    }
  }

  public static HashAndLength md5AndLength(InputStream inputStream) throws IOException {
    MessageDigest digest = buildMd5();
    return hash(digest, inputStream);
  }

  public static HashAndLength hash(MessageDigest digest, File file) throws IOException {
    InputStream is = new FileInputStream(file);
    try {
      return hash(digest, is);
    } finally {
      IoUtils.safeClose(is);
    }
  }

  // public static HashAndLength hash(MessageDigest digest, File file, long segmentOffset, long segmentLength) throws
  // IOException {
  // InputStream is = IoUtils.openFileSegment(file, segmentOffset, segmentLength);
  // try {
  // return hash(digest, is);
  // } finally {
  // IoUtils.safeClose(is);
  // }
  // }

  private static HashAndLength hash(MessageDigest digest, InputStream inputStream) throws IOException {
    byte[] buffer = new byte[32768];

    long totalBytesRead = 0;
    while (true) {
      int bytesRead = inputStream.read(buffer);
      if (bytesRead < 0) {
        break;
      }
      totalBytesRead += bytesRead;
      digest.update(buffer, 0, bytesRead);
    }

    byte[] hash = digest.digest();

    return new HashAndLength(hash, totalBytesRead);
  }

  public static MessageDigest buildMd5() {
    try {
      MessageDigest digest = MessageDigest.getInstance("MD5");
      return digest;
    } catch (NoSuchAlgorithmException e) {
      // should not happen
      throw new RuntimeException("Could not find md5 algorithm", e);
    }
  }

  public static Sha1Hash sha1(File file) throws IOException {
    MessageDigest digest = getThreadLocalSha1();
    return new Sha1Hash(hash(digest, file).hash);
  }

  public static Md5Hash md5(File file) throws IOException {
    MessageDigest digest = buildMd5();
    return new Md5Hash(hash(digest, file).hash);
  }

  public static byte[] generateSecureRandom(int length) {
    synchronized (SECURE_RANDOM) {
      byte[] data = new byte[length];
      SECURE_RANDOM.nextBytes(data);
      return data;
    }
  }

  public static KeyPair generateKeyPair(String algorithm, int keysize) {
    KeyPairGenerator generator;
    try {
      generator = KeyPairGenerator.getInstance(algorithm);
    } catch (NoSuchAlgorithmException e) {
      throw new IllegalStateException("Error loading crypto provider", e);
    }
    generator.initialize(keysize);
    KeyPair keyPair = generator.generateKeyPair();
    return keyPair;

  }

  public static SecretKey generateKey(String algorithm, int keysize) {
    KeyGenerator generator;
    try {
      generator = KeyGenerator.getInstance(algorithm);
    } catch (NoSuchAlgorithmException e) {
      throw new IllegalStateException("Error loading crypto provider", e);
    }
    generator.init(keysize);
    SecretKey key = generator.generateKey();
    return key;

  }

  public static Cipher getCipher(String algorithm) {
    try {
      return Cipher.getInstance(algorithm);
    } catch (NoSuchAlgorithmException e) {
      throw new IllegalArgumentException("Error loading crypto provider", e);
    } catch (NoSuchPaddingException e) {
      throw new IllegalArgumentException("Error loading crypto provider", e);
    }
  }

  public static byte[] decrypt(Cipher cipher, Key key, byte[] cipherText) {
    initDecrypt(cipher, key);
    byte[] plainText;
    try {
      plainText = cipher.doFinal(cipherText);
    } catch (IllegalBlockSizeException e) {
      throw new IllegalArgumentException("Error in decryption", e);
    } catch (BadPaddingException e) {
      throw new IllegalArgumentException("Error in decryption", e);
    }
    return plainText;
  }

  public static void initDecrypt(Cipher cipher, Key key) {
    try {
      cipher.init(Cipher.DECRYPT_MODE, key);
    } catch (InvalidKeyException e) {
      throw new IllegalArgumentException("Invalid key", e);
    }
  }

  public static void initEncrypt(Cipher cipher, Key key) {
    try {
      cipher.init(Cipher.ENCRYPT_MODE, key);
    } catch (InvalidKeyException e) {
      throw new IllegalArgumentException("Invalid key", e);
    }
  }

  public static byte[] encrypt(Cipher cipher, Key key, byte[] plaintext) {
    initEncrypt(cipher, key);
    byte[] encryptedBytes;
    try {
      encryptedBytes = cipher.doFinal(plaintext);
    } catch (IllegalBlockSizeException e) {
      throw new IllegalArgumentException("Error in encryption", e);
    } catch (BadPaddingException e) {
      throw new IllegalArgumentException("Error in encryption", e);
    }
    return encryptedBytes;
  }

  public static byte[] concat(byte[]... arrays) {
    int length = 0;
    for (int i = 0; i < arrays.length; i++) {
      length += arrays[i].length;
    }
    byte[] dest = new byte[length];
    int pos = 0;
    for (int i = 0; i < arrays.length; i++) {
      System.arraycopy(arrays[i], 0, dest, pos, arrays[i].length);
      pos += arrays[i].length;
    }
    return dest;
  }

}
TOP

Related Classes of org.platformlayer.crypto.CryptoUtils$HashAndLength

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.