Java с использованием шифрования AES 256 и 128 с симметричным ключом - PullRequest
12 голосов
/ 30 июня 2011

Я новичок в технологии шифрования. Я нашел этот код для симметричного шифрования.

byte[] key = //... secret sequence of bytes
byte[] dataToSend = ...
Cipher c = Cipher.getInstance("AES");
SecretKeySpec k = new SecretKeySpec(key, "AES");
c.init(Cipher.ENCRYPT_MODE, k);
byte[] encryptedData = c.doFinal(dataToSend);

Это работает. Здесь я могу использовать свой собственный пароль. И это именно то, что мне было нужно. Но я не знаю, как сделать 128 или 256 симметричного шифрования. Как я могу использовать ключи 128 и 256 в своем коде?

Ответы [ 5 ]

16 голосов
/ 30 июня 2011

Использует ли AES режим 128 или 256 бит, зависит от размера вашего ключа, который должен быть длиной 128 или 256 бит. Обычно вы не используете свой пароль в качестве ключа, потому что пароли редко имеют точную длину, как вам нужно. Вместо этого вы получаете ключ шифрования из своего пароля, используя некоторую функцию получения ключа.

Очень простой пример: возьмите MD5 вашего пароля для получения 128-битного ключа. Если вам нужен 256-битный ключ, вы можете использовать SHA-256 для получения 256-битного хэша вашего пароля. Функции вывода ключей обычно выполняют это хеширование несколько сотен раз, а также используют дополнительное количество соли. Проверьте http://en.wikipedia.org/wiki/Key_derivation_function для деталей.

Также обратите внимание: для запуска шифрования, более мощного, чем 128-битное, вам необходимо загрузить и установить «Файлы политики шифрования неограниченной силы Java 6» с неограниченным набором правил шифрования (JCE), начиная с http://www.oracle.com/technetwork/java/javase/downloads/index.html.

6 голосов
/ 20 мая 2015

Ответ для 128-битного

Следующий метод заключается в шифровании строки (valueEnc) с шифрованием AES:

private static final String ALGORITHM = "AES"; 

public String encrypt(final String valueEnc, final String secKey) { 

    String encryptedVal = null;

    try {
        final Key key = generateKeyFromString(secKey);
        final Cipher c = Cipher.getInstance(ALGORITHM);
        c.init(Cipher.ENCRYPT_MODE, key);
        final byte[] encValue = c.doFinal(valueEnc.getBytes());
        encryptedVal = new BASE64Encoder().encode(encValue);
    } catch(Exception ex) {
        System.out.println("The Exception is=" + ex);
    }

    return encryptedVal;
}

Следующий метод расшифрует зашифрованную строку AES (encryptedVal):

    public String decrypt(final String encryptedValue, final String secretKey) {

    String decryptedValue = null;

    try {

        final Key key = generateKeyFromString(secretKey);
        final Cipher c = Cipher.getInstance(ALGORITHM);
        c.init(Cipher.DECRYPT_MODE, key);
        final byte[] decorVal = new BASE64Decoder().decodeBuffer(encryptedValue);
        final byte[] decValue = c.doFinal(decorVal);
        decryptedValue = new String(decValue);
    } catch(Exception ex) {
        System.out.println("The Exception is=" + ex);
    }

    return decryptedValue;
}

secKey - это 128-битный ключ, который закодирован в BASE64Encoder.BASE64Decoder в следующем методе генерирует соответствующий 128-битный ключ

private Key generateKeyFromString(final String secKey) throws Exception {
    final byte[] keyVal = new BASE64Decoder().decodeBuffer(secKey);
    final Key key = new SecretKeySpec(keyVal, ALGORITHM);
    return key;
}
3 голосов
/ 30 июня 2011

Вы можете использовать простой объект KeyGenerator, например так:

KeyGenerator generator = KeyGenerator.getInstance("AES/CTR/PKCS5PADDING");
generator.init(128);
SecretKey key = generator.generateKey();
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key);
...
1 голос
/ 30 июня 2011

С Документы Java для Cipher.init(...):

public final void init (int opmode, Key key)

Throws: InvalidKeyException - если заданоключ не подходит для инициализации этого шифра, или если этот шифр инициализируется для дешифрования и требует параметров алгоритма, которые не могут быть определены по данному ключу, или если данный ключ имеет размер ключа, который превышает максимально допустимый размер ключа (как определено из сконфигурированногофайлы политики юрисдикции).

Для меня это означает, что, как сказал Мартин Курто в своем комментарии, вы должны использовать ключ размером 256 бит (т.е. инициализировать SecretKeySpec байтовым массивом, содержащим 32 байта)и шифр примет его и будет использовать, или отклонит, и выдаст исключение, если его размер неприемлем.

Если вы получаете исключение, это, вероятно, потому, что вы не установили файлы шифрования неограниченной силы,(установка JDK по умолчанию позволяет использовать 128-битные ключи, как описано в этом документе по криптографиилор ).Загрузите криптопакет неограниченной силы здесь .

0 голосов
/ 20 мая 2015
public class CipherUtils
{
    private static byte[] key = {
            0x74, 0x68, 0x69, 0x73, 0x49, 0x73, 0x41, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79
    };//"thisIsASecretKey";

    public static String encrypt(String strToEncrypt)
    {
        try
        {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            final SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            final String encryptedString = Base64.encodeBase64String(cipher.doFinal(strToEncrypt.getBytes()));
            return encryptedString;
        }
        catch (Exception e)
        {
           e.printStackTrace();
        }
        return null;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...