#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();