Давайте посмотрим на ваш код Java:
String c = new String(Test.encrypt((new String("thevalue")).getBytes(),
(new String("mykey")).getBytes()));
...
System.out.println("Base64 encoded String:" +
new sun.misc.BASE64Encoder().encode(c.getBytes()));
Что вы здесь делаете:
- Преобразование строки открытого текста в байты, используя кодировку системы по умолчанию
- преобразует ключ в байты, используя системную кодировку по умолчанию
- шифрует байты
- преобразует зашифрованные байты обратно в строку , используя системную настройку по умолчаниюкодировка
- преобразовывает зашифрованную строку обратно в байты , используя системную кодировку по умолчанию
- , кодирует эти зашифрованные байты, используя Base64.
Проблеманаходится в шаге 4. Предполагается, что произвольный байтовый массив представляет строку в кодировке вашей системы по умолчанию, а обратное кодирование этой строки дает тот же байт [].Это справедливо для некоторых кодировок (например, для серии ISO-8859
), но не для других.В Java, когда некоторый байт (или последовательность байтов) не может быть представлен в данной кодировке, он будет заменен другим символом, который позже для повторного преобразования будет отображен в байт 63 (ASCII ?
).На самом деле, в документации даже сказано:
Поведение этого конструктора, когда указанные байты недопустимы в кодировке по умолчанию, не указано.
В вашем случае естьнет никакой причины делать это вообще - просто используйте байты, которые ваш метод encrypt
выводит напрямую, чтобы преобразовать их в Base64.
byte[] encrypted = Test.encrypt("thevalue".getBytes(),
"mykey".getBytes());
System.out.println("Base64 encoded String:"+ new sun.misc.BASE64Encoder().encode(encrypted));
(Также обратите внимание, что я удалил лишние вызовы конструктора new String("...")
здесь,хотя это не относится к вашей проблеме.)
Следует помнить: Никогда не преобразовывать произвольный байт [], который не был получен при кодировании строки, в строку. Выводалгоритма шифрования (и большинства других криптографических алгоритмов, кроме дешифрования), безусловно, относится к категории данных, которые не следует преобразовывать в строку .
и никогда не использовать кодировку по умолчанию системы, если вы хотите переносимые программы.