What Java encryption algorithms should I use? [closed]

て烟熏妆下的殇ゞ 提交于 2019-12-06 02:06:18

问题


I'm working on a program that needs to store binary information encrypted at rest. Unfortunately, I can't seem to find a resource that explains which encryption schemes are best for different applications.

Since encryption is complicated and I'm not an expert, I've decided to use a library called Jasypt that wraps Java's built-in encryption functions. To figure out what algorithms are available to me, I wrote a few unit tests.

The first test calls Jasypt's AlgorithmRegistry.getAllPBEAlgorithms() function and lists out all available encryption algorithms:

PBEWITHHMACSHA1ANDAES_128
PBEWITHHMACSHA1ANDAES_256
PBEWITHHMACSHA224ANDAES_128
PBEWITHHMACSHA224ANDAES_256
PBEWITHHMACSHA256ANDAES_128
PBEWITHHMACSHA256ANDAES_256
PBEWITHHMACSHA384ANDAES_128
PBEWITHHMACSHA384ANDAES_256
PBEWITHHMACSHA512ANDAES_128
PBEWITHHMACSHA512ANDAES_256
PBEWITHMD5ANDDES
PBEWITHMD5ANDTRIPLEDES
PBEWITHSHA1ANDDESEDE
PBEWITHSHA1ANDRC2_128
PBEWITHSHA1ANDRC2_40
PBEWITHSHA1ANDRC4_128
PBEWITHSHA1ANDRC4_40

At runtime, Jasypt will throw an EncryptionOperationNotPossibleException if you try to use an algorithm that for some reason isn't supported or violates Java's encryption rules. Interestingly, if I attempt to use each of the 'available' algorithms to encrypt and then decrypt some arbitrary data, and only print out the ones that don't throw that exception, I get this slimmed down list:

PBEWITHMD5ANDDES
PBEWITHSHA1ANDDESEDE
PBEWITHSHA1ANDRC2_128
PBEWITHSHA1ANDRC2_40
PBEWITHSHA1ANDRC4_128
PBEWITHSHA1ANDRC4_40

The list of available algorithms can be expanded by pulling in the BouncyCastle JCE and registering it by executing Security.addProvider(new BouncyCastleProvider()). If I repeat the previous test after doing this, I get a much bigger list of algorithms to choose from:

PBEWITHMD2ANDDES
PBEWITHMD5AND128BITAES-CBC-OPENSSL
PBEWITHMD5AND192BITAES-CBC-OPENSSL
PBEWITHMD5AND256BITAES-CBC-OPENSSL
PBEWITHMD5ANDDES
PBEWITHMD5ANDRC2
PBEWITHSHA1ANDDES
PBEWITHSHA1ANDDESEDE
PBEWITHSHA1ANDRC2
PBEWITHSHA1ANDRC2_128
PBEWITHSHA1ANDRC2_40
PBEWITHSHA1ANDRC4_128
PBEWITHSHA1ANDRC4_40
PBEWITHSHA256AND128BITAES-CBC-BC
PBEWITHSHA256AND192BITAES-CBC-BC
PBEWITHSHA256AND256BITAES-CBC-BC
PBEWITHSHAAND128BITAES-CBC-BC
PBEWITHSHAAND128BITRC2-CBC
PBEWITHSHAAND128BITRC4
PBEWITHSHAAND192BITAES-CBC-BC
PBEWITHSHAAND2-KEYTRIPLEDES-CBC
PBEWITHSHAAND256BITAES-CBC-BC
PBEWITHSHAAND3-KEYTRIPLEDES-CBC
PBEWITHSHAAND40BITRC2-CBC
PBEWITHSHAAND40BITRC4
PBEWITHSHAANDIDEA-CBC
PBEWITHSHAANDTWOFISH-CBC

Unfortunately, now I have no idea which of these many algorithms is most appropriate for my application. I have an inkling that AES is the right way to go, and it looks like PBEWITHSHA256AND256BITAES-CBC-BC is the AES implementation with the longest key length, but I don't know where to go to confirm that suspicion.

Which of these schemes would provide the highest security levels and which have obvious security issues?

EDIT: I want to be able to distribute my code without requiring the end user to install the unlimited cryptography files, as that will almost certainly be beyond the capabilities of not so tech savvy users. What I really want is the strongest encryption that I can get without using the unlimited strength jurisdiction files.


回答1:


First of all you should install the unlimited cryptography files from Oracle. After doing so you should have fewer EncryptionOperationNotPossibleExceptions and higher security levels should become available.

Furthermore, for the highest level encryption possible I would not use JaSypt at all, because it doesn't seem to provide any integrity checking or authentication of ciphertext. For just confidentiality that doesn't seem to matter. But in practice you'd need to check that against your threat model.

If you'd decide to use JaSypt (which I personally dislike) you should probably go for PBEWITHHMACSHA512ANDAES_256 as highest level possibility. Make sure you understand PBKDF2 and work factors (iteration count, e.g. setKeyObtentionIterations.

You don't need Bouncy Castle. AES is considered secure; all Bouncy Castle does - for your example that uses JaSypt - is adding obscure ciphers. In the above list, everything other than AES is less secure than AES.




回答2:


The original question that you had was how to encrypt data. What algorithm to use and what java library?

package cryptography;

import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.KeySpec;

import javax.crypto.Cipher;
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;

import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;

public class BasicAESEncrypt {
private final byte[] SALT = {
        (byte) 0xA9, (byte) 0x9B, (byte) 0xC8, (byte) 0x32,
        (byte) 0x56, (byte) 0x35, (byte) 0xE3, (byte) 0x03
    };

private Cipher ecipher;
private Cipher dcipher;
Encoder encoder = Base64.getEncoder();
Decoder decoder = Base64.getDecoder();


BasicAESEncrypt(String password) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, InvalidParameterSpecException, InvalidAlgorithmParameterException{
    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

    KeySpec spec = new PBEKeySpec(password.toCharArray(), SALT, 65536, 256);
    SecretKey tmp = factory.generateSecret(spec);        

    SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

    ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    ecipher.init(Cipher.ENCRYPT_MODE, secret);

    AlgorithmParameters params = ecipher.getParameters();
    byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();

    dcipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    dcipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
}

public String encrypt(String encrypt) throws Exception {
    byte[] bytes = encrypt.getBytes("UTF8");
    byte[] encrypted = encrypt(bytes);
    return encoder.encodeToString(encrypted);
}

public byte[] encrypt(byte[] plain) throws Exception {
    return ecipher.doFinal(plain);
}

public String decrypt(String encrypt) throws Exception {
    byte[] decodedData = decoder.decode(encrypt);
    byte[] decrypted = decrypt(decodedData);
    return new String(decrypted, "UTF8");
}

public byte[] decrypt(byte[] encrypt) throws Exception {
    return dcipher.doFinal(encrypt);
}

public static void main(String[] args) throws Exception {
    String message = "Wire message for encryption";
    String password  = "TopSecretKey";

    try {
        BasicAESEncrypt app = new BasicAESEncrypt(password);

        String encrypted = app.encrypt(message);
        System.out.println("Encrypted string is: " + encrypted);

        String decrypted = app.decrypt(encrypted);
        System.out.println("Decrypted string is: " + decrypted);
    } catch (InvalidKeyException | NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException
            | InvalidParameterSpecException | InvalidAlgorithmParameterException e1) {
        e1.printStackTrace();
    }
    try {
    } catch (Exception e) {
        e.printStackTrace();
    }
}

}



来源:https://stackoverflow.com/questions/35685679/what-java-encryption-algorithms-should-i-use

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!