В одном из наших внутренних программных продуктов мы внедряем новую конечную точку API, к которой внешние источники должны получать доступ через Интернет, а затем она должна быть каким-то образом защищена.
Так как нам не разрешено использовать библиотеку в качестве OAuth
или открытых и закрытых ключей, мы выбрали javax.crypto AES
, чтобы таким образом отобрать «токен авторизации» в каждом внешнем источнике:
...
Key aesKey = new SecretKeySpec("API-KEY".getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, aesKey);
byte[] applicationIdEncrypted = cipher.doFinal(applicationId.getBytes());
...
token
содержит пользовательский applicationId
для идентификации на другой стороне, кто связывается с этой конечной точкой.
Поскольку мы должны выполнить HTTP-вызов, мы конвертируем applicationIdEncrypted
в строку base64
String base64Encoded = Base64.getEncoder().encodeToString(applicationIdEncrypted);
НА ДРУГОЙ СТОРОНЕ
Мы получаем заголовок и декодируем его из base64
String base64Decoded = new String(Base64.getDecoder().decode(header));
Но при попытке выполнить последнюю операцию
Key aesKey = new SecretKeySpec("API-KEY".getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, aesKey);
String headerDecoded = new String(cipher.doFinal(base64Decoded.getBytes())); //<- THIS
Мы получили javax.crypto.BadPaddingException: Given final block not properly padded
Оба base64Encoded
и base64Decoded
имеют одинаковое значение на обоих концах.
Попытка выполнить одну и ту же операцию в одном из концов (чтобы не использовать канал HTTP) не выдается никаких исключений -но, но new String(cipher.doFinal(base64Decoded.getBytes()));
возвращает другое
headerDecoded
Искал байты applicationIdEncrypted
и base64Decoded.getBytes()
, и они немного отличаются:
applicationIdEncrypted
[-28, -103, 107, 70, -112, 121, 4, -14, -80, -114, -14, 92, -81, -13, -128, 97]
base64Decoded.getBytes ()
[-28, -103, 107, 70, 63, 121, 4, -14, -80, -114, -14, 92, -81, -13, -128, 97]
Я читал, что, возможно, переход от байтов к String может быть потерей информации (возможно?), Но я не могу понять, почему такого поведения, так как base64Encoded
и base64Decoded
имеют то же значение в обоих случаях и сценариях .
Как я могу добиться передачи "пользовательского токена авторизации", используя только библиотеки Java 1.7 javax.crypto
?
EDIT
"API-KEY"
- это что-то вроде 02E30E6BE24BF1EA