Some fixes in Encrypter
This commit is contained in:
parent
051f6fdcf8
commit
73868960f4
3 changed files with 164 additions and 110 deletions
|
|
@ -26,11 +26,12 @@ package zutil;
|
||||||
|
|
||||||
import javax.crypto.*;
|
import javax.crypto.*;
|
||||||
import javax.crypto.spec.PBEKeySpec;
|
import javax.crypto.spec.PBEKeySpec;
|
||||||
import javax.crypto.spec.PBEParameterSpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
import java.security.spec.AlgorithmParameterSpec;
|
import java.security.spec.AlgorithmParameterSpec;
|
||||||
|
import java.security.spec.InvalidKeySpecException;
|
||||||
import java.security.spec.KeySpec;
|
import java.security.spec.KeySpec;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
|
@ -39,22 +40,58 @@ import java.util.Random;
|
||||||
* Basic symmetric encryption example
|
* Basic symmetric encryption example
|
||||||
*/
|
*/
|
||||||
public class Encrypter {
|
public class Encrypter {
|
||||||
public static final String BLOWFISH_ALGO = "Blowfish";
|
// Choices are available at: http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html
|
||||||
public static final String DES_ALGO = "DES";
|
public enum Algorithm {
|
||||||
public static final String DESEDE_ALGO = "DESede";
|
/** Advanced Encryption Standard as specified by NIST in FIPS 197. Also known as the Rijndael algorithm by Joan Daemen and Vincent Rijmen, AES is a 128-bit block cipher supporting keys of 128, 192, and 256 bits. **/
|
||||||
public static final String TRIPLEDES_ALGO = "TripleDES";
|
AES,
|
||||||
public static final String AES_ALGO = "AES";
|
/** The AES key wrapping algorithm as described in RFC 3394. **/
|
||||||
public static final String PASSPHRASE_TOWFISH_ALGO = "PBEWithSHAAndTwofish-CBC";
|
AESWrap,
|
||||||
public static final String PASSPHRASE_TRIPLEDES_ALGO = "PBEWithMD5AndTripleDES";
|
/** A stream cipher believed to be fully interoperable with the RC4 cipher developed by Ron Rivest. For more information, see K. Kaukonen and R. Thayer, "A Stream Cipher Encryption Algorithm 'Arcfour'", Internet Draft (expired), draft-kaukonen-cipher-arcfour-03.txt. **/
|
||||||
public static final String PASSPHRASE_DES_ALGO = "PBEWithMD5AndDES";
|
ARCFOUR,
|
||||||
|
/** The Blowfish block cipher designed by Bruce Schneier. **/
|
||||||
|
Blowfish,
|
||||||
|
/** Counter/CBC Mode, as defined in NIST Special Publication SP 800-38C. **/
|
||||||
|
CCM,
|
||||||
|
/** The Digital Encryption Standard as described in FIPS PUB 46-3. **/
|
||||||
|
DES,
|
||||||
|
/** Triple DES Encryption (also known as DES-EDE, 3DES, or Triple-DES). Data is encrypted using the DES algorithm three separate times. It is first encrypted using the first subkey, then decrypted with the second subkey, and encrypted with the third subkey. **/
|
||||||
|
DESede,
|
||||||
|
/** The DESede key wrapping algorithm as described in RFC 3217 . **/
|
||||||
|
DESedeWrap,
|
||||||
|
/** Elliptic Curve Integrated Encryption Scheme **/
|
||||||
|
ECIES,
|
||||||
|
/** Galois/Counter Mode, as defined in NIST Special Publication SP 800-38D. **/
|
||||||
|
GCM,
|
||||||
|
/** Variable-key-size encryption algorithms developed by Ron Rivest for RSA Data Security, Inc. **/
|
||||||
|
RC2,
|
||||||
|
/** Variable-key-size encryption algorithms developed by Ron Rivest for RSA Data Security, Inc. (See note prior for ARCFOUR.) **/
|
||||||
|
RC4,
|
||||||
|
/** Variable-key-size encryption algorithms developed by Ron Rivest for RSA Data Security, Inc. **/
|
||||||
|
RC5,
|
||||||
|
/** The RSA encryption algorithm as defined in PKCS #1 **/
|
||||||
|
RSA
|
||||||
|
}
|
||||||
|
public enum Digest {
|
||||||
|
MD2,
|
||||||
|
MD5,
|
||||||
|
SHA1,
|
||||||
|
SHA256,
|
||||||
|
SHA384,
|
||||||
|
SHA512,
|
||||||
|
HmacMD5,
|
||||||
|
HmacSHA1,
|
||||||
|
HmacSHA256,
|
||||||
|
HmacSHA384,
|
||||||
|
HmacSHA512
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 8-byte Salt
|
// 8-byte Salt
|
||||||
public static byte[] salt = {
|
public static byte[] salt = {
|
||||||
(byte)0xA9, (byte)0x9B, (byte)0xC8, (byte)0x32,
|
(byte)0xA9, (byte)0x9B, (byte)0xC8, (byte)0x32,
|
||||||
(byte)0x56, (byte)0x35, (byte)0xE3, (byte)0x03
|
(byte)0x56, (byte)0x35, (byte)0xE3, (byte)0x03
|
||||||
};
|
};
|
||||||
// Iteration count
|
|
||||||
public static int iterationCount = 19;
|
|
||||||
|
|
||||||
private Cipher encipher;
|
private Cipher encipher;
|
||||||
private Cipher decipher;
|
private Cipher decipher;
|
||||||
|
|
@ -63,10 +100,10 @@ public class Encrypter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a random key
|
* Generates a random key
|
||||||
* @param algorithm The algorithm to use
|
* @param crypto is algorithm to encrypt/decrypt with
|
||||||
*/
|
*/
|
||||||
public Encrypter(String algorithm) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException{
|
public Encrypter(Algorithm crypto) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException{
|
||||||
KeyGenerator keygenerator = KeyGenerator.getInstance(algorithm);
|
KeyGenerator keygenerator = KeyGenerator.getInstance(crypto.toString());
|
||||||
|
|
||||||
key = keygenerator.generateKey();
|
key = keygenerator.generateKey();
|
||||||
encipher = Cipher.getInstance(key.getAlgorithm());
|
encipher = Cipher.getInstance(key.getAlgorithm());
|
||||||
|
|
@ -77,7 +114,7 @@ public class Encrypter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uses the given key for encryption
|
* Uses the given key for encryption
|
||||||
* @param key The key to use
|
* @param key is an existing key to use for encrypting/decrypting
|
||||||
*/
|
*/
|
||||||
public Encrypter(Key key) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException{
|
public Encrypter(Key key) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException{
|
||||||
this.key = key;
|
this.key = key;
|
||||||
|
|
@ -88,36 +125,42 @@ public class Encrypter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a encrypter with a passphrase
|
* Creates a encrypter with a passphrase.
|
||||||
*
|
*
|
||||||
* @param stringKey The pass
|
* @param stringKey is a passphrase to use as key
|
||||||
* @param algorithm The algoritm to use
|
* @param crypto is algorithm to encrypt/decrypt with
|
||||||
*/
|
*/
|
||||||
public Encrypter(String stringKey, String algorithm) throws NoSuchAlgorithmException{
|
public Encrypter(String stringKey, Algorithm crypto) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, InvalidKeyException {
|
||||||
try {
|
this(stringKey, Digest.HmacSHA1, crypto, 500,
|
||||||
// Install SunJCE provider
|
(crypto==Algorithm.DES ? 64 : 128));
|
||||||
Provider sunJce = new com.sun.crypto.provider.SunJCE();
|
|
||||||
Security.addProvider(sunJce);
|
|
||||||
|
|
||||||
// Generate the secret key specs.
|
|
||||||
KeySpec keySpec = new PBEKeySpec(stringKey.toCharArray());
|
|
||||||
|
|
||||||
key = SecretKeyFactory.getInstance(algorithm).generateSecret(keySpec);
|
|
||||||
paramSpec = new PBEParameterSpec(salt, iterationCount);
|
|
||||||
|
|
||||||
encipher = Cipher.getInstance(key.getAlgorithm());
|
|
||||||
decipher = Cipher.getInstance(key.getAlgorithm());
|
|
||||||
encipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
|
|
||||||
decipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Encrypter(String stringKey, Digest digest, Algorithm crypto, int iteration, int keyBitSize) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException {
|
||||||
|
// Install SunJCE provider
|
||||||
|
Provider sunJce = new com.sun.crypto.provider.SunJCE();
|
||||||
|
Security.addProvider(sunJce);
|
||||||
|
|
||||||
|
// Generate the secret key specs.
|
||||||
|
//String instance = "PBEWith"+ digest +"And"+ crypto;
|
||||||
|
String instance = "PBKDF2With"+ digest;
|
||||||
|
SecretKeyFactory factory = SecretKeyFactory.getInstance(instance);
|
||||||
|
KeySpec keySpec = new PBEKeySpec(stringKey.toCharArray(), salt, iteration, keyBitSize);
|
||||||
|
SecretKey tmp = factory.generateSecret(keySpec);
|
||||||
|
key = new SecretKeySpec(tmp.getEncoded(), crypto.toString());
|
||||||
|
//key = new SecretKeySpec(stringKey.getBytes(), crypto.toString());
|
||||||
|
|
||||||
|
encipher = Cipher.getInstance(key.getAlgorithm());
|
||||||
|
decipher = Cipher.getInstance(key.getAlgorithm());
|
||||||
|
encipher.init(Cipher.ENCRYPT_MODE, key);
|
||||||
|
decipher.init(Cipher.DECRYPT_MODE, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encrypts the given data
|
* Encrypts the given data
|
||||||
*
|
*
|
||||||
* @param data Data to encrypt
|
* @param data is the data to encrypt
|
||||||
* @return The encrypted data
|
* @return The encrypted data
|
||||||
*/
|
*/
|
||||||
public byte[] encrypt(byte[] data){
|
public byte[] encrypt(byte[] data){
|
||||||
|
|
@ -135,7 +178,7 @@ public class Encrypter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds encryption to the OutputStream
|
* Adds encryption to the OutputStream
|
||||||
* @param out The OutputStream to enable encryption on
|
* @param out is the OutputStream to enable encryption on
|
||||||
* @return A new encrypted OutputStream
|
* @return A new encrypted OutputStream
|
||||||
*/
|
*/
|
||||||
public OutputStream encrypt(OutputStream out) {
|
public OutputStream encrypt(OutputStream out) {
|
||||||
|
|
@ -146,7 +189,7 @@ public class Encrypter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decrypts encrypted data
|
* Decrypts encrypted data
|
||||||
* @param encrypted The encrypted data
|
* @param encrypted is the encrypted data
|
||||||
* @return The decrypted data
|
* @return The decrypted data
|
||||||
*/
|
*/
|
||||||
public byte[] decrypt(byte[] encrypted){
|
public byte[] decrypt(byte[] encrypted){
|
||||||
|
|
@ -166,7 +209,7 @@ public class Encrypter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds decryption to the InputStream
|
* Adds decryption to the InputStream
|
||||||
* @param in The InputStream to enable decryption on
|
* @param in is the InputStream to enable decryption on
|
||||||
* @return A new decrypted InputStream
|
* @return A new decrypted InputStream
|
||||||
*/
|
*/
|
||||||
public InputStream decrypt(InputStream in) {
|
public InputStream decrypt(InputStream in) {
|
||||||
|
|
@ -183,7 +226,7 @@ public class Encrypter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The algorithm used by this encrypter
|
* @return the algorithm used by this encrypter
|
||||||
*/
|
*/
|
||||||
public String getAlgorithm(){
|
public String getAlgorithm(){
|
||||||
return key.getAlgorithm();
|
return key.getAlgorithm();
|
||||||
|
|
|
||||||
72
test/zutil/test/EncrypterTest.java
Normal file
72
test/zutil/test/EncrypterTest.java
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Ziver Koc
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package zutil.test;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import zutil.Encrypter;
|
||||||
|
import zutil.Encrypter.*;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class EncrypterTest {
|
||||||
|
public static final String data = "Hello there, wats yor name, my is a secret, 123456789";
|
||||||
|
public static final String key = "abcdefghijklmnopqrstuvwxyz";
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void encryptDES() throws Exception {
|
||||||
|
Encrypter.randomizeSalt();
|
||||||
|
Encrypter encrypter = new Encrypter(key, Algorithm.DES);
|
||||||
|
Encrypter decrypter = new Encrypter(key, Algorithm.DES);
|
||||||
|
|
||||||
|
assertEquals(data, encryptDecrypt(encrypter, decrypter, data));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void encryptBLOWFISH() throws Exception {
|
||||||
|
Encrypter.randomizeSalt();
|
||||||
|
Encrypter encrypter = new Encrypter(Algorithm.Blowfish);
|
||||||
|
Encrypter.randomizeSalt();
|
||||||
|
Encrypter decrypter = new Encrypter(encrypter.getKey());
|
||||||
|
|
||||||
|
assertEquals(data, encryptDecrypt(encrypter, decrypter, data));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void encryptAES() throws Exception {
|
||||||
|
Encrypter.randomizeSalt();
|
||||||
|
Encrypter encrypter = new Encrypter(key, Algorithm.AES);
|
||||||
|
Encrypter decrypter = new Encrypter(key, Algorithm.AES);
|
||||||
|
|
||||||
|
assertEquals(data, encryptDecrypt(encrypter, decrypter, data));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static String encryptDecrypt(Encrypter encrypter, Encrypter decrypter, String data){
|
||||||
|
byte[] encrypted = encrypter.encrypt(data.getBytes());
|
||||||
|
byte[] decrypted = decrypter.decrypt(encrypted);
|
||||||
|
return new String(decrypted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015 Ziver Koc
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package zutil.test;
|
|
||||||
|
|
||||||
import zutil.Encrypter;
|
|
||||||
|
|
||||||
public class EncryptionTest {
|
|
||||||
public static String data = "Hello there wats yor name my is a secret 123456789";
|
|
||||||
public static Encrypter enc;
|
|
||||||
public static Encrypter enc2;
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
|
||||||
System.out.println("input text : " + data);
|
|
||||||
|
|
||||||
//****************************************************************************************
|
|
||||||
System.out.println("Test1 passphrase");
|
|
||||||
Encrypter.randomizeSalt();
|
|
||||||
enc = new Encrypter("Hello World!!", Encrypter.PASSPHRASE_DES_ALGO);
|
|
||||||
enc2 = new Encrypter("Hello World!!", Encrypter.PASSPHRASE_DES_ALGO);
|
|
||||||
|
|
||||||
byte[] encrypted = enc.encrypt(data.getBytes());
|
|
||||||
System.out.println("cipher text: " + new String(encrypted) + " bytes: " + encrypted.length);
|
|
||||||
|
|
||||||
byte[] decrypted = enc2.decrypt(encrypted);
|
|
||||||
System.out.println("plain text : " + new String(decrypted) + " bytes: " + decrypted.length);
|
|
||||||
|
|
||||||
//****************************************************************************************
|
|
||||||
System.out.println("Test2 randome");
|
|
||||||
Encrypter.randomizeSalt();
|
|
||||||
enc = new Encrypter(Encrypter.BLOWFISH_ALGO);
|
|
||||||
Encrypter.randomizeSalt();
|
|
||||||
enc2 = new Encrypter(enc.getKey());
|
|
||||||
|
|
||||||
encrypted = enc.encrypt(data.getBytes());
|
|
||||||
System.out.println("cipher text: " + new String(encrypted) + " bytes: " + encrypted.length);
|
|
||||||
|
|
||||||
decrypted = enc2.decrypt(encrypted);
|
|
||||||
System.out.println("plain text : " + new String(decrypted) + " bytes: " + decrypted.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue