在JAVA中快速简单的stringencryption/解密

我需要快速和简单的方式来encryption/解密一大堆string数据。 我试过jasypt,但是在我的Android手机上崩溃了。 我有大约2000个logging (string)。

BasicTextEncryptor textEncryptor = new BasicTextEncryptor(); textEncryptor.setPassword("password"); String myEncryptedText = textEncryptor.encrypt(input); 

有其他的方法吗? 我不需要非常高的安全性,它需要快速

Java – 从configuration文件encryption/解密用户名和密码

上面的代码链接

 DESKeySpec keySpec = new DESKeySpec("Your secret Key phrase".getBytes("UTF8")); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey key = keyFactory.generateSecret(keySpec); sun.misc.BASE64Encoder base64encoder = new BASE64Encoder(); sun.misc.BASE64Decoder base64decoder = new BASE64Decoder(); ......... // ENCODE plainTextPassword String byte[] cleartext = plainTextPassword.getBytes("UTF8"); Cipher cipher = Cipher.getInstance("DES"); // cipher is not thread safe cipher.init(Cipher.ENCRYPT_MODE, key); String encryptedPwd = base64encoder.encode(cipher.doFinal(cleartext)); // now you can store it ...... // DECODE encryptedPwd String byte[] encrypedPwdBytes = base64decoder.decodeBuffer(encryptedPwd); Cipher cipher = Cipher.getInstance("DES");// cipher is not thread safe cipher.init(Cipher.DECRYPT_MODE, key); byte[] plainTextPwdBytes = (cipher.doFinal(encrypedPwdBytes)); 

更新

该库已经有Java / Kotlin支持,请参阅github 。


原版的

为了简化我做了一个简单的类,我把它添加到encryption库来使用它,你只需要做如下:

添加gradle库:

 compile 'se.simbio.encryption:library:2.0.0' 

并使用它:

 Encryption encryption = Encryption.getDefault("Key", "Salt", new byte[16]); String encrypted = encryption.encryptOrNull("top secret string"); String decrypted = encryption.decryptOrNull(encrypted); 

如果您不想添加encryption库 ,则可以将以下类复制到您的项目中。 如果你在一个android项目,你需要在这个类中导入android base64 ,如果你在一个纯java项目中,你需要手动添加这个类,你可以在这里

Encryption.java

 package se.simbio.encryption; import java.io.UnsupportedEncodingException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; /** * A class to make more easy and simple the encrypt routines, this is the core of Encryption library */ public class Encryption { /** * The Builder used to create the Encryption instance and that contains the information about * encryption specifications, this instance need to be private and careful managed */ private final Builder mBuilder; /** * The private and unique constructor, you should use the Encryption.Builder to build your own * instance or get the default proving just the sensible information about encryption */ private Encryption(Builder builder) { mBuilder = builder; } /** * @return an default encryption instance or {@code null} if occur some Exception, you can * create yur own Encryption instance using the Encryption.Builder */ public static Encryption getDefault(String key, String salt, byte[] iv) { try { return Builder.getDefaultBuilder(key, salt, iv).build(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } } /** * Encrypt a String * * @param data the String to be encrypted * * @return the encrypted String or {@code null} if you send the data as {@code null} * * @throws UnsupportedEncodingException if the Builder charset name is not supported or if * the Builder charset name is not supported * @throws NoSuchAlgorithmException if the Builder digest algorithm is not available * or if this has no installed provider that can * provide the requested by the Builder secret key * type or it is {@code null}, empty or in an invalid * format * @throws NoSuchPaddingException if no installed provider can provide the padding * scheme in the Builder digest algorithm * @throws InvalidAlgorithmParameterException if the specified parameters are inappropriate for * the cipher * @throws InvalidKeyException if the specified key can not be used to initialize * the cipher instance * @throws InvalidKeySpecException if the specified key specification cannot be used * to generate a secret key * @throws BadPaddingException if the padding of the data does not match the * padding scheme * @throws IllegalBlockSizeException if the size of the resulting bytes is not a * multiple of the cipher block size * @throws NullPointerException if the Builder digest algorithm is {@code null} or * if the specified Builder secret key type is * {@code null} * @throws IllegalStateException if the cipher instance is not initialized for * encryption or decryption */ public String encrypt(String data) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, InvalidKeySpecException, BadPaddingException, IllegalBlockSizeException { if (data == null) return null; SecretKey secretKey = getSecretKey(hashTheKey(mBuilder.getKey())); byte[] dataBytes = data.getBytes(mBuilder.getCharsetName()); Cipher cipher = Cipher.getInstance(mBuilder.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, secretKey, mBuilder.getIvParameterSpec(), mBuilder.getSecureRandom()); return Base64.encodeToString(cipher.doFinal(dataBytes), mBuilder.getBase64Mode()); } /** * This is a sugar method that calls encrypt method and catch the exceptions returning * {@code null} when it occurs and logging the error * * @param data the String to be encrypted * * @return the encrypted String or {@code null} if you send the data as {@code null} */ public String encryptOrNull(String data) { try { return encrypt(data); } catch (Exception e) { e.printStackTrace(); return null; } } /** * This is a sugar method that calls encrypt method in background, it is a good idea to use this * one instead the default method because encryption can take several time and with this method * the process occurs in a AsyncTask, other advantage is the Callback with separated methods, * one for success and other for the exception * * @param data the String to be encrypted * @param callback the Callback to handle the results */ public void encryptAsync(final String data, final Callback callback) { if (callback == null) return; new Thread(new Runnable() { @Override public void run() { try { String encrypt = encrypt(data); if (encrypt == null) { callback.onError(new Exception("Encrypt return null, it normally occurs when you send a null data")); } callback.onSuccess(encrypt); } catch (Exception e) { callback.onError(e); } } }).start(); } /** * Decrypt a String * * @param data the String to be decrypted * * @return the decrypted String or {@code null} if you send the data as {@code null} * * @throws UnsupportedEncodingException if the Builder charset name is not supported or if * the Builder charset name is not supported * @throws NoSuchAlgorithmException if the Builder digest algorithm is not available * or if this has no installed provider that can * provide the requested by the Builder secret key * type or it is {@code null}, empty or in an invalid * format * @throws NoSuchPaddingException if no installed provider can provide the padding * scheme in the Builder digest algorithm * @throws InvalidAlgorithmParameterException if the specified parameters are inappropriate for * the cipher * @throws InvalidKeyException if the specified key can not be used to initialize * the cipher instance * @throws InvalidKeySpecException if the specified key specification cannot be used * to generate a secret key * @throws BadPaddingException if the padding of the data does not match the * padding scheme * @throws IllegalBlockSizeException if the size of the resulting bytes is not a * multiple of the cipher block size * @throws NullPointerException if the Builder digest algorithm is {@code null} or * if the specified Builder secret key type is * {@code null} * @throws IllegalStateException if the cipher instance is not initialized for * encryption or decryption */ public String decrypt(String data) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { if (data == null) return null; byte[] dataBytes = Base64.decode(data, mBuilder.getBase64Mode()); SecretKey secretKey = getSecretKey(hashTheKey(mBuilder.getKey())); Cipher cipher = Cipher.getInstance(mBuilder.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, secretKey, mBuilder.getIvParameterSpec(), mBuilder.getSecureRandom()); byte[] dataBytesDecrypted = (cipher.doFinal(dataBytes)); return new String(dataBytesDecrypted); } /** * This is a sugar method that calls decrypt method and catch the exceptions returning * {@code null} when it occurs and logging the error * * @param data the String to be decrypted * * @return the decrypted String or {@code null} if you send the data as {@code null} */ public String decryptOrNull(String data) { try { return decrypt(data); } catch (Exception e) { e.printStackTrace(); return null; } } /** * This is a sugar method that calls decrypt method in background, it is a good idea to use this * one instead the default method because decryption can take several time and with this method * the process occurs in a AsyncTask, other advantage is the Callback with separated methods, * one for success and other for the exception * * @param data the String to be decrypted * @param callback the Callback to handle the results */ public void decryptAsync(final String data, final Callback callback) { if (callback == null) return; new Thread(new Runnable() { @Override public void run() { try { String decrypt = decrypt(data); if (decrypt == null) { callback.onError(new Exception("Decrypt return null, it normally occurs when you send a null data")); } callback.onSuccess(decrypt); } catch (Exception e) { callback.onError(e); } } }).start(); } /** * creates a 128bit salted aes key * * @param key encoded input key * * @return aes 128 bit salted key * * @throws NoSuchAlgorithmException if no installed provider that can provide the requested * by the Builder secret key type * @throws UnsupportedEncodingException if the Builder charset name is not supported * @throws InvalidKeySpecException if the specified key specification cannot be used to * generate a secret key * @throws NullPointerException if the specified Builder secret key type is {@code null} */ private SecretKey getSecretKey(char[] key) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeySpecException { SecretKeyFactory factory = SecretKeyFactory.getInstance(mBuilder.getSecretKeyType()); KeySpec spec = new PBEKeySpec(key, mBuilder.getSalt().getBytes(mBuilder.getCharsetName()), mBuilder.getIterationCount(), mBuilder.getKeyLength()); SecretKey tmp = factory.generateSecret(spec); return new SecretKeySpec(tmp.getEncoded(), mBuilder.getKeyAlgorithm()); } /** * takes in a simple string and performs an sha1 hash * that is 128 bits long...we then base64 encode it * and return the char array * * @param key simple inputted string * * @return sha1 base64 encoded representation * * @throws UnsupportedEncodingException if the Builder charset name is not supported * @throws NoSuchAlgorithmException if the Builder digest algorithm is not available * @throws NullPointerException if the Builder digest algorithm is {@code null} */ private char[] hashTheKey(String key) throws UnsupportedEncodingException, NoSuchAlgorithmException { MessageDigest messageDigest = MessageDigest.getInstance(mBuilder.getDigestAlgorithm()); messageDigest.update(key.getBytes(mBuilder.getCharsetName())); return Base64.encodeToString(messageDigest.digest(), Base64.NO_PADDING).toCharArray(); } /** * When you encrypt or decrypt in callback mode you get noticed of result using this interface */ public interface Callback { /** * Called when encrypt or decrypt job ends and the process was a success * * @param result the encrypted or decrypted String */ void onSuccess(String result); /** * Called when encrypt or decrypt job ends and has occurred an error in the process * * @param exception the Exception related to the error */ void onError(Exception exception); } /** * This class is used to create an Encryption instance, you should provide ALL data or start * with the Default Builder provided by the getDefaultBuilder method */ public static class Builder { private byte[] mIv; private int mKeyLength; private int mBase64Mode; private int mIterationCount; private String mSalt; private String mKey; private String mAlgorithm; private String mKeyAlgorithm; private String mCharsetName; private String mSecretKeyType; private String mDigestAlgorithm; private String mSecureRandomAlgorithm; private SecureRandom mSecureRandom; private IvParameterSpec mIvParameterSpec; /** * @return an default builder with the follow defaults: * the default char set is UTF-8 * the default base mode is Base64 * the Secret Key Type is the PBKDF2WithHmacSHA1 * the default salt is "some_salt" but can be anything * the default length of key is 128 * the default iteration count is 65536 * the default algorithm is AES in CBC mode and PKCS 5 Padding * the default secure random algorithm is SHA1PRNG * the default message digest algorithm SHA1 */ public static Builder getDefaultBuilder(String key, String salt, byte[] iv) { return new Builder() .setIv(iv) .setKey(key) .setSalt(salt) .setKeyLength(128) .setKeyAlgorithm("AES") .setCharsetName("UTF8") .setIterationCount(1) .setDigestAlgorithm("SHA1") .setBase64Mode(Base64.DEFAULT) .setAlgorithm("AES/CBC/PKCS5Padding") .setSecureRandomAlgorithm("SHA1PRNG") .setSecretKeyType("PBKDF2WithHmacSHA1"); } /** * Build the Encryption with the provided information * * @return a new Encryption instance with provided information * * @throws NoSuchAlgorithmException if the specified SecureRandomAlgorithm is not available * @throws NullPointerException if the SecureRandomAlgorithm is {@code null} or if the * IV byte array is null */ public Encryption build() throws NoSuchAlgorithmException { setSecureRandom(SecureRandom.getInstance(getSecureRandomAlgorithm())); setIvParameterSpec(new IvParameterSpec(getIv())); return new Encryption(this); } /** * @return the charset name */ private String getCharsetName() { return mCharsetName; } /** * @param charsetName the new charset name * * @return this instance to follow the Builder patter */ public Builder setCharsetName(String charsetName) { mCharsetName = charsetName; return this; } /** * @return the algorithm */ private String getAlgorithm() { return mAlgorithm; } /** * @param algorithm the algorithm to be used * * @return this instance to follow the Builder patter */ public Builder setAlgorithm(String algorithm) { mAlgorithm = algorithm; return this; } /** * @return the key algorithm */ private String getKeyAlgorithm() { return mKeyAlgorithm; } /** * @param keyAlgorithm the keyAlgorithm to be used in keys * * @return this instance to follow the Builder patter */ public Builder setKeyAlgorithm(String keyAlgorithm) { mKeyAlgorithm = keyAlgorithm; return this; } /** * @return the Base 64 mode */ private int getBase64Mode() { return mBase64Mode; } /** * @param base64Mode set the base 64 mode * * @return this instance to follow the Builder patter */ public Builder setBase64Mode(int base64Mode) { mBase64Mode = base64Mode; return this; } /** * @return the type of aes key that will be created, on KITKAT+ the API has changed, if you * are getting problems please @see <a href="http://android-developers.blogspot.com.br/2013/12/changes-to-secretkeyfactory-api-in.html">http://android-developers.blogspot.com.br/2013/12/changes-to-secretkeyfactory-api-in.html</a> */ private String getSecretKeyType() { return mSecretKeyType; } /** * @param secretKeyType the type of AES key that will be created, on KITKAT+ the API has * changed, if you are getting problems please @see <a href="http://android-developers.blogspot.com.br/2013/12/changes-to-secretkeyfactory-api-in.html">http://android-developers.blogspot.com.br/2013/12/changes-to-secretkeyfactory-api-in.html</a> * * @return this instance to follow the Builder patter */ public Builder setSecretKeyType(String secretKeyType) { mSecretKeyType = secretKeyType; return this; } /** * @return the value used for salting */ private String getSalt() { return mSalt; } /** * @param salt the value used for salting * * @return this instance to follow the Builder patter */ public Builder setSalt(String salt) { mSalt = salt; return this; } /** * @return the key */ private String getKey() { return mKey; } /** * @param key the key. * * @return this instance to follow the Builder patter */ public Builder setKey(String key) { mKey = key; return this; } /** * @return the length of key */ private int getKeyLength() { return mKeyLength; } /** * @param keyLength the length of key * * @return this instance to follow the Builder patter */ public Builder setKeyLength(int keyLength) { mKeyLength = keyLength; return this; } /** * @return the number of times the password is hashed */ private int getIterationCount() { return mIterationCount; } /** * @param iterationCount the number of times the password is hashed * * @return this instance to follow the Builder patter */ public Builder setIterationCount(int iterationCount) { mIterationCount = iterationCount; return this; } /** * @return the algorithm used to generate the secure random */ private String getSecureRandomAlgorithm() { return mSecureRandomAlgorithm; } /** * @param secureRandomAlgorithm the algorithm to generate the secure random * * @return this instance to follow the Builder patter */ public Builder setSecureRandomAlgorithm(String secureRandomAlgorithm) { mSecureRandomAlgorithm = secureRandomAlgorithm; return this; } /** * @return the IvParameterSpec bytes array */ private byte[] getIv() { return mIv; } /** * @param iv the byte array to create a new IvParameterSpec * * @return this instance to follow the Builder patter */ public Builder setIv(byte[] iv) { mIv = iv; return this; } /** * @return the SecureRandom */ private SecureRandom getSecureRandom() { return mSecureRandom; } /** * @param secureRandom the Secure Random * * @return this instance to follow the Builder patter */ public Builder setSecureRandom(SecureRandom secureRandom) { mSecureRandom = secureRandom; return this; } /** * @return the IvParameterSpec */ private IvParameterSpec getIvParameterSpec() { return mIvParameterSpec; } /** * @param ivParameterSpec the IvParameterSpec * * @return this instance to follow the Builder patter */ public Builder setIvParameterSpec(IvParameterSpec ivParameterSpec) { mIvParameterSpec = ivParameterSpec; return this; } /** * @return the message digest algorithm */ private String getDigestAlgorithm() { return mDigestAlgorithm; } /** * @param digestAlgorithm the algorithm to be used to get message digest instance * * @return this instance to follow the Builder patter */ public Builder setDigestAlgorithm(String digestAlgorithm) { mDigestAlgorithm = digestAlgorithm; return this; } } } 

最简单的方法是使用Gradle添加这个JAVA库:

 compile 'se.simbio.encryption:library:2.0.0' 

你可以像这样简单地使用它:

 Encryption encryption = Encryption.getDefault("Key", "Salt", new byte[16]); String encrypted = encryption.encryptOrNull("top secret string"); String decrypted = encryption.decryptOrNull(encrypted); 

如果你使用Android,那么你可以使用android.util.Base64类。

编码:

 passwd = Base64.encodeToString( passwd.getBytes(), Base64.DEFAULT ); 

解码:

 passwd = new String( Base64.decode( passwd, Base64.DEFAULT ) ); 

一个简单而快速的单线解决scheme。