/* * Copyright 2008-2016 the original author or authors. * * 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 com.nominanuda.zen.codec; import java.nio.charset.Charset; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.Mac; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.SecretKeySpec; import static com.nominanuda.zen.codec.Base62.B62; import static com.nominanuda.zen.codec.Base64Codec.B64; import static com.nominanuda.zen.common.Str.UTF8; import static javax.crypto.Cipher.DECRYPT_MODE; import static javax.crypto.Cipher.ENCRYPT_MODE; public class Digester { private static final String BLOWFISH = "Blowfish"; private static final String SHA1 = "SHA1"; private static final String AES = "AES"; private static final String MD5 = "MD5"; private static final String HMAC_SHA256 = "HmacSHA256"; private SecretKeySpec aes128SecretKey, sha256SecretKey, blowfish128SecretKey; private Charset charset = UTF8; // default UTF8 public static class Digest { private byte[] b; public Digest(byte[] digest) { b = digest; } public String toBase64Classic() { return B64.encodeClassic(b); } public String toBase64GzipClassic() { return B64.gzipEncodeClassic(b); } public String toBase64UrlSafeNoPad() { return B64.encodeUrlSafeNoPad(b); } public String toBase62() { return B62.encode(b); } public String toBase64GzipUrlSafeNoPad() { return B64.gzipEncodeUrlSafeNoPad(b); } public String toHex() { return Hex.encode(b); } public byte[] unwrap() { return b; } } public Digest hmacSHA256(String value) throws NoSuchAlgorithmException, InvalidKeyException { Mac mac = Mac.getInstance(HMAC_SHA256); mac.init(sha256SecretKey); return new Digest(mac.doFinal(stringToBytes(value))); } public String hash(String seed, int nchars) { return sha1(seed).toBase64UrlSafeNoPad().substring(0, nchars); } public String hash(byte[] seed, int nchars) { return sha1(seed).toBase64UrlSafeNoPad().substring(0, nchars); } public Digest md5(String seed) { try { return md5(stringToBytes(seed)); } catch (Exception e) { throw new IllegalStateException(e); } } public Digest md5(byte[] seed) { try { MessageDigest md = MessageDigest.getInstance(MD5); md.update(seed); return new Digest(md.digest()); } catch (NoSuchAlgorithmException e) { throw new IllegalStateException(e); } } public Digest encriptAes128(byte[] clearMessage) { try { Cipher cipher = Cipher.getInstance(AES); cipher.init(ENCRYPT_MODE, aes128SecretKey); byte[] encrypted = cipher.doFinal(clearMessage); return new Digest(encrypted); } catch (NoSuchAlgorithmException e) { throw new IllegalStateException(e); } catch (NoSuchPaddingException e) { throw new IllegalStateException(e); } catch (InvalidKeyException e) { throw new IllegalStateException(e); } catch (IllegalBlockSizeException e) { throw new IllegalStateException(e); } catch (BadPaddingException e) { throw new IllegalStateException(e); } } public byte[] decriptAes128(byte[] encrypted) { try { Cipher cipher = Cipher.getInstance(AES); cipher.init(DECRYPT_MODE, aes128SecretKey); return cipher.doFinal(encrypted); } catch (NoSuchAlgorithmException e) { throw new IllegalStateException(e); } catch (NoSuchPaddingException e) { throw new IllegalStateException(e); } catch (InvalidKeyException e) { throw new IllegalStateException(e); } catch (IllegalBlockSizeException e) { throw new IllegalStateException(e); } catch (BadPaddingException e) { throw new IllegalStateException(e); } } public Digest encriptBlowfish128(byte[] clearMessage) { try { Cipher cipher = Cipher.getInstance(BLOWFISH); cipher.init(ENCRYPT_MODE, blowfish128SecretKey); byte[] encrypted = cipher.doFinal(clearMessage); return new Digest(encrypted); } catch (NoSuchAlgorithmException e) { throw new IllegalStateException(e); } catch (NoSuchPaddingException e) { throw new IllegalStateException(e); } catch (InvalidKeyException e) { throw new IllegalStateException(e); } catch (IllegalBlockSizeException e) { throw new IllegalStateException(e); } catch (BadPaddingException e) { throw new IllegalStateException(e); } } public byte[] decriptBlowfish128(byte[] encrypted) { try { Cipher cipher = Cipher.getInstance(BLOWFISH); cipher.init(DECRYPT_MODE, blowfish128SecretKey); return cipher.doFinal(encrypted); } catch (NoSuchAlgorithmException e) { throw new IllegalStateException(e); } catch (NoSuchPaddingException e) { throw new IllegalStateException(e); } catch (InvalidKeyException e) { throw new IllegalStateException(e); } catch (IllegalBlockSizeException e) { throw new IllegalStateException(e); } catch (BadPaddingException e) { throw new IllegalStateException(e); } } public Digest sha1(byte[] seed) { try { MessageDigest md = MessageDigest.getInstance(SHA1); md.update(seed); return new Digest(md.digest()); } catch (Exception e) { throw new IllegalStateException(e); } } public Digest sha1(String seed) { try { return sha1(stringToBytes(seed)); } catch (Exception e) { throw new IllegalStateException(e); } } private byte[] stringToBytes(String seed) { return seed.getBytes(charset); } public Digester withCharset(String cs) { setCharset(cs); return this; } public void setCharset(String cs) { charset = Charset.forName(cs); } public Digester withSecretKeySpec(String secretKey) { setSecretKeySpec(secretKey); return this; } public void setSecretKeySpec(String secretKey) { byte[] b = stringToBytes(secretKey); aes128SecretKey = new SecretKeySpec(Arrays.copyOf(b, 16), AES); sha256SecretKey = new SecretKeySpec(Arrays.copyOf(b, 32), HMAC_SHA256); blowfish128SecretKey = new SecretKeySpec(Arrays.copyOf(b, 16), BLOWFISH); } }