All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.yapbam.util.Crypto Maven / Gradle / Ivy

There is a newer version: 1.9.1
Show newest version
package net.yapbam.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.security.AccessControlException;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/** Utilities to encrypt data.
 * @author Jean-Marc Astesana
 * 
License : GPL v3 */ public final class Crypto { public static final String UTF8 = "UTF-8"; //$NON-NLS-1$ static final String ALGORITHM = "PBEWITHMD5ANDDES"; //$NON-NLS-1$ // An interesting article to implement file encryption : http://java.sun.com/j2se/1.4.2/docs/guide/security/jce/JCERefGuide.html private Crypto(){ // Nothing to do } /** Decrypt a text previously crypted by the encrypt method. * @param key The secret key used for the encryption * @param message The encrypted message we want to decrypt * @return the decrypted message * @see #encrypt(String, String) */ public static String decrypt(String key, String message) { SecretKeySpec skeySpec; Cipher cipher; skeySpec = new SecretKeySpec(CheckSum.toBytes(key), "AES"); try { cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, skeySpec); return new String(cipher.doFinal(CheckSum.toBytes(message))); } catch (GeneralSecurityException e) { throw new RuntimeException(e); } } /** Encrypt a text. *
It uses a symmetric AES algorithm. * @param key The secret key used for the encryption (secret key is the hexadecimal representation of a (128 bits long key = 8 bytes => 16 characters between 0 and F)) * @param message The message we want to encrypt * @return the encrypted message * @see #decrypt(String, String) */ public static String encrypt(String key, String message) { SecretKey skeySpec = new SecretKeySpec(CheckSum.toBytes(key), "AES"); try { Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec); return CheckSum.toString(cipher.doFinal(message.getBytes())); } catch (GeneralSecurityException e) { throw new RuntimeException(e); } } private static final byte[] SALT = new byte[]{ (byte)0xc7, (byte)0x23, (byte)0xa5, (byte)0xfc, (byte)0x7e, (byte)0x38, (byte)0xee, (byte)0x09}; private static final PBEParameterSpec PBE_PARAM_SPEC = new PBEParameterSpec(SALT, 16); /** Encrypt an output stream. *
The returned stream is deflated and encrypted with the password accordingly to the PBEWithMD5AndDES algorithm. * @param password The password used to encrypt the stream. * @param stream The stream to encrypt. * @return A new stream that encrypt data written to it. * @see #getPasswordProtectedInputStream(String, InputStream) * @throws IOException If an error occurs */ public static OutputStream getPasswordProtectedOutputStream (String password, OutputStream stream) throws IOException { stream.write(getDigest(password)); try { SecretKey pbeKey = getSecretKey(password); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, pbeKey, PBE_PARAM_SPEC); CipherOutputStream cstream = new CipherOutputStream(stream, cipher); stream = new DeflaterOutputStream(cstream) { /* (non-Javadoc) * @see java.util.zip.DeflaterOutputStream#finish() */ @Override public void finish() throws IOException { super.finish(); ((CipherOutputStream)out).finish(); } }; return stream; } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } catch (InvalidKeySpecException e) { throw new RuntimeException(e); } catch (NoSuchPaddingException e) { throw new RuntimeException(e); } catch (InvalidKeyException e) { throw new RuntimeException(e); } catch (InvalidAlgorithmParameterException e) { throw new RuntimeException(e); } } /** Decrypt an input stream. *
The data in the stream may have been encoded using a stream return by getPasswordProtectedOutputStream. * @param password The password used to encrypt the data. * @param stream The stream on the encrypted data * @return a new InputStream, data read from this stream is decrypted. * @see #getPasswordProtectedOutputStream(String, OutputStream) * @throws IOException If an errors occurs while creating the stream * @throws GeneralSecurityException if the password is invalid * @deprecated This implementation hangs on Android platform. It remains only for compatibility with previous releases */ @Deprecated public static InputStream getOldPasswordProtectedInputStream (String password, InputStream stream) throws IOException, AccessControlException, GeneralSecurityException { // This doesn't work on Android platform SecretKey pbeKey = new BinaryPBEKey(password.getBytes(UTF8)); return getPasswordProtectedInputStream(password, stream, pbeKey); } /** Decrypt an input stream. *
The data in the stream may have been encoded using a stream return by getPasswordProtectedOutputStream. * @param password The password used to encrypt the data. * @param stream The stream on the encrypted data * @return a new InputStream, data read from this stream is decrypted. * @see #getPasswordProtectedOutputStream(String, OutputStream) * @throws IOException If an errors occurs while creating the stream * @throws GeneralSecurityException if the password is invalid */ public static InputStream getPasswordProtectedInputStream (String password, InputStream stream) throws IOException, AccessControlException, GeneralSecurityException { return getPasswordProtectedInputStream(password, stream, getSecretKey(password)); } private static SecretKey getSecretKey(String password) throws InvalidKeySpecException, NoSuchAlgorithmException { try { password = Base64Encoder.encode(password.getBytes(UTF8)); return SecretKeyFactory.getInstance(ALGORITHM).generateSecret(new PBEKeySpec(password.toCharArray())); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } private static InputStream getPasswordProtectedInputStream (String password, InputStream stream, SecretKey key) throws IOException, AccessControlException, GeneralSecurityException { verifyPassword(stream, password); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, key, PBE_PARAM_SPEC); stream = new CipherInputStream(stream, cipher); stream = new InflaterInputStream(stream); return stream; } /** Checks if the input stream is protected with a password. * @param stream The password protected stream * @param password The password to check * @throws IOException If an errors occurs while reading the stream * @throws AccessControlException if the password is wrong */ public static void verifyPassword(InputStream stream, String password) throws IOException, AccessControlException { byte[] digest = getDigest(password); byte[] fileDigest = new byte[digest.length]; for (int missing=fileDigest.length; missing>0; ) { missing -= stream.read(fileDigest, fileDigest.length-missing, missing); } if (!MessageDigest.isEqual(digest, fileDigest)) { throw new AccessControlException("invalid password"); } } /** Gets the SHA digest of a password. * @param password The password * @return The password digest. */ public static byte[] getDigest(String password) { try { MessageDigest digest = MessageDigest.getInstance("SHA"); digest.update(SALT); return digest.digest(password.getBytes(UTF8)); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy