#android #node.js #caesar-cipher #aes-gcm
#Android #node.js #caesar-cipher #aes-gcm
Вопрос:
Вот мой метод шифрования, также метод дешифрования, он отлично работает с тегом, в основном серверу нужен ТЕГ, возможно ли, что сервер находит тег по моей шестнадцатеричной строке, потому что каждая строка, которую я отправляю тегу на сервер, а также с шестнадцатеричным, есть ли у него какое-либо другое оптимальное решение
aesKey=context.getString(R.string.aes_key).getBytes();
iv=context.getString(R.string.input_vector).getBytes();
public Map encrypt(String string){
byte[] plainText= new byte[0];
try {
plainText = string.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Cipher cipher = null;
try {
cipher = Cipher.getInstance("AES/GCM/NoPadding");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
try {
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(aesKey, "AES"), new IvParameterSpec(iv));
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
byte[] cipherText = new byte[0];
byte[] tag = new byte[0];
try {
cipherText = cipher.doFinal(plainText);
tag= Arrays.copyOfRange(cipherText, cipherText.length -16, cipherText.length);
cipherText= Arrays.copyOfRange(cipherText, 0, cipherText.length -16);
Log.d("testing", "encrypt: " byteArrayToHexString(tag));
Map<String, Object> map=new HashMap();
map.put("content",byteArrayToHexString(cipherText));
map.put("tag",tag);
Log.d("testing", "encrypt: " new Gson().toJson(map));
return map;
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return new HashMap();
}
Серверу нужен шестнадцатеричный код, поэтому я конвертирую его в шестнадцатеричный
public String byteArrayToHexString(final byte[] bytes) {
StringBuilder sb = new StringBuilder();
for(byte b : bytes){
sb.append(String.format("x", bamp;0xff));
}
return sb.toString();
}
Моя функция дешифрования заключается в том, что возвращает мне строку, которую я получаю, тег и шестнадцатеричную строку с сервера
public String decrypt(String content,byte[] tag){
byte[] cipherText = hexStringToByteArray(content byteArrayToHexString(tag));
Cipher cipher = null;
try {
cipher = Cipher.getInstance("AES/GCM/NoPadding");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
try {
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(aesKey, "AES"), new IvParameterSpec(iv));
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
byte[] plainText = new byte[0];
try {
plainText = cipher.doFinal(cipherText);
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
try {
Log.d("testing", "encrypt: plain text:" new String(plainText,"UTF-8"));
return new String(plainText,"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
Комментарии:
1. Интересно, действительно ли этот код выполняется в вашей среде. На моем компьютере
InvalidAlgorithmParameterException
( Неподдерживаемый параметр: javax.crypto.spec. Выбрасывается IvParameterSpec ), потому что для GCM на самом деле вместоGCMParameterSpec
используется aIvParameterSpec
. Когда эта проблема устранена, шифрование выполняется успешно.2. Какую версию Java и какую среду вы используете? Я не уверен, почему вы можете запускать
AES/GCM/NoPadding
в сочетании сIvParameterSpec
. На самом деле GCM нуженGCMParameterSpec
, который позволяет явно указывать длину тега. Обычно длина тега для GCM составляет 16 байт, а IV — 12 байт. Код, размещенный в комментарии, отделяет тег размером 16 байт от зашифрованного текста.3. Хорошо для Android API, по-видимому,
AES/GCM/NoPadding
также работает в сочетании сIvParameterSpec
, сгенерированный тег имеет длину 16 байт. ПоэтомуGCMParameterSpec
здесь не обязательно обязательно использовать. Это не работает в Java API, здесьGCMParameterSpec
необходимо использовать. К вашему сведению: длина тега (независимо от того, использовался лиIvParameterSpec
илиGCMParameterSpec
) может быть определена с помощьюcipher.getParameters().getParameterSpec(GCMParameterSpec.class).getTLen()
.4. На ваши вопросы: есть ли в Android какой-либо другой способ или функция для получения тега? Насколько мне известно, нет (т. Е. вам всегда нужно разделять).
5. Есть ли какой-либо возможный способ, если я не отправляю тег на сервер, а сервер узла расшифровывает мою строку? Вы ничего не опубликовали о реализации GCM на сайте NodeJS, поэтому я могу ответить только в общих чертах: преимущество GCM — это тег, то есть аутентификация. GCM без аутентификации имеет мало смысла, тогда вы также можете использовать режим без аутентификации. В принципе, однако, при 12 байтах IV для GCM возможно дешифрование без тега, смотрите здесь . Но это должно быть реализовано (т. Е. По умолчанию это не работает так).