Хеширование с использованием SHA 256 и шифрование с использованием AES

#java #encryption #hash #aes

#java #шифрование #хэш #aes

Вопрос:

Для того, чтобы я мог использовать веб-сервис, мне нужно сгенерировать значение для имени заголовка Authorization . Шаги для создания заголовка следующие:

 1. Hash Generation

   HashValue = SHA2(username, password, id)

2. Auth Key Generation

   Authkey = AES(Salt   anotherId   "="   HashValue)
  

Это детали алгоритмов:

 Algorithm - AES
Mode - ECB
Padding - PKCS5Padding
Secret key - someString
  

Теперь я буду выполнять шифрование AES, используя вышеуказанные детали и секретный ключ, который представляет собой строку.

После шифрования я буду использовать сгенерированное выше зашифрованное значение в качестве a header в моем вызове службы rest.

Я сделал это до сих пор:

 String username = "username";
String password = "password";
String id = "123456"; 

String toBeHashed = username   password   id;
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
byte[] hashed = sha256.digest(toBeHashed.getBytes("UTF-8"));

String hashString = "="   Base64.encodeBase64String(hashed);
System.out.println(hashString);

String salt = "salt";
String anotherId = "123";
byte[] forAuth = (salt   orgId   hashString).getBytes("UTF-8");

//Mocked "secret key". Original key string is of size 16 bytes.
byte[] secKey = "secret key".getBytes("UTF-8");

SecretKey secretKey = new SecretKeySpec(secKey, 0, secKey.length, "AES");

Cipher aesCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
aesCipher.init(Cipher.ENCRYPT_MODE, secretKey);

byte[] authorizationKey = aesCipher.doFinal(forAuth);

System.out.println("-------------------");
System.out.println("-------------------");
System.out.println(Base64.encodeBase64String(authorizationKey));
  

Но все же серверная служба сообщает, что мой ключ авторизации недействителен. Пожалуйста, скажите мне, если я чего-то не хватает.

Комментарии:

1. Длина ключа AES составляет 16, 24 или 32 байта, поэтому ваш ключ AES в принципе недействителен. Ваш провайдер может интерпретировать такой недопустимый ключ иначе, чем вы ожидаете.

2. На самом деле я издевался над секретным ключом здесь. Когда я пытаюсь преобразовать исходную строку ключа в байты и получить длину, она равна 16. Поэтому я думаю, что это не проблема. Я отредактирую это в вопросе.

3. Это выглядит непоследовательно (хэш-функция имеет ровно один вход, а блочный шифр имеет ровно 2 входа) и неполно (1. SHA-2? Существуют разные длины. 2. Как выполняется кодирование?) документация веб-службы. Просто попросите у них пример кода или лучшую документацию.

Ответ №1:

     **Encrypt and Decrypt using AES** 
    
    public static String encrypt(String value) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
        IvParameterSpec iv = new IvParameterSpec("randomStringVec".getBytes("UTF-8"));
        SecretKeySpec skeySpec = new SecretKeySpec("randomStringKey".getBytes("UTF-8"), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(1, skeySpec, iv);

        byte[] encrypted = cipher.doFinal(value.getBytes());
        return Base64.encodeBase64String(encrypted);
    }

    public static String decrypt(String encrypted) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
        IvParameterSpec iv = new IvParameterSpec("randomStringVec".getBytes("UTF-8"));
        SecretKeySpec skeySpec = new SecretKeySpec("randomStringKey".getBytes("UTF-8"), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(2, skeySpec, iv);
        byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));

        return new String(original);
    }


    **Encryption Using SHA256**
    private static String encrypt256(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {

        MessageDigest crypt = MessageDigest.getInstance("SHA-256");
        crypt.reset();
        crypt.update(password.getBytes("UTF-8"));
        return new BigInteger(1, crypt.digest()).toString(16);
    }
  

Ответ №2:

Вам нужно изменить это:

 String hashString = "="   Base64.encodeBase64String(hashed);
System.out.println(hashString);
  

Для:

 String hashString = "="   new String(hashed);
System.out.println(hashString);
  

Поскольку хэшированный ключ получает base64encoded перед генерацией ключа авторизации.

Комментарии:

1. hashed является byte[] содержащим двоичные данные. Никогда не пытайтесь вызывать new String(byte[]) нестроковые данные!!!

2. Можете ли вы попробовать это: ByteArrayOutputStream OutputStream = new ByteArrayOutputStream(); OutputStream.write( (соль OrgID «=»).getByte()); OutputStream.write( хэшированный); байт forAuth[] = OutputStream.toByteArray();