Что делает метод обновления MessageDigest и для чего предназначен BASE64Encoder? - PullRequest
8 голосов
/ 22 февраля 2012

Ниже приведен код, который зашифрует строку пользователя:

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import sun.misc.BASE64Encoder;
import java.io.*;

class Encrypter {
public synchronized String encrypt(String plainText) throws Exception {
    MessageDigest md = null;
    try {
        md = MessageDigest.getInstance("SHA");
    }catch(Exception exc) {
        throw new Exception(exc.getMessage());
     }

     try {
        md.update(plainText.getBytes("UTF-8"));
     }catch(Exception exc) {
        throw new Exception(exc.getMessage());
      }

      byte raw[] = md.digest();
      String hash = (new BASE64Encoder()).encode(raw);
      return hash;
}
public static void main(String args[]) {
    try {
        Encrypter encrypter = new Encrypter();
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String userInput = br.readLine();
        String encryptedPassword = encrypter.encrypt(userInput);
        System.out.println(encryptedPassword);
    } catch(Exception exc) {
        System.out.println(exc);
      }
}
}

Когда я компилирую код, я получаю следующие предупреждения:

Encrypter.java:4: warning: BASE64Encoder is internal proprietary API and may be removed in a future release
import sun.misc.BASE64Encoder;
           ^
Encrypter.java:23: warning: BASE64Encoder is internal proprietary API and may be removed in a future release
              String hash = (new BASE64Encoder()).encode(raw);
                                 ^
2 warnings

Есть ли какие-либо другиеметод для шифрования строк в Java?

Что делает метод update класса MessageDigest?т.е. что делает утверждение md.update(plainText.getBytes("UTF-8"));?

Что такое класс BASE64Encoder?Я не мог найти это DOC

Ответы [ 5 ]

13 голосов
/ 22 февраля 2012
  1. Прежде всего, вы не выполняете шифрование. Вы вычисляете односторонний хэш или дайджест вашего ввода. Этот хэш может быть позже использован для проверки целостности сообщения. См. Хеширование , SHA1 и MessageDigest .

  2. Кодировка Base64 - это метод представления двоичных данных в ASCII. Это часто желательно, потому что не все механизмы хранения и передачи данных поддерживают необработанный двоичный файл. Например, если вы хотите передать свой вычисленный дайджест с помощью параметра строки запроса http, вам необходимо закодировать его как Base64. Кроме того, сохранение или распечатка сырых двоичных файлов на консоль приведет к появлению потока забавных символов, которые могут находиться за пределами диапазона печати, а также могут издавать звуковые сигналы из динамика компьютера!

  3. Используемый вами Base64Encoder поставляется из пакета sun.misc и НИКОГДА не должен использоваться. Это внутренний код Sun JVM, который может быть или не быть доступным в будущем. Это также объясняет, почему вы не смогли найти ни одного javadoc.

  4. К счастью, существует несколько свободных и открытых кодеров и декодеров Base64. Кодек Apache Commons - это широко используемая и стабильная библиотека, которая содержит несколько кодеков, включая Base64 .

  5. md.update(plainText.getBytes("UTF-8")) обновляет ввод в дайджест. Вызов digest выполняет окончательное обновление и вычисляет дайджест ввода. См. Javadoc md.digest и md.update

2 голосов
/ 10 февраля 2017

Пока в старом посте есть обновленный ответ.Java 8 Base64.

Java 8 Base64 Документы

2 голосов
/ 22 февраля 2012
1 голос
/ 14 августа 2012

Для шифрования и дешифрования Base64 это предупреждение ясно говорит о том, что оно не поощряет использование реализации Base64Encoder от Sun и предупреждает, что реализация может быть удалена в будущих выпусках, что мы можем сделать, это переключиться на другую реализацию Base64кодировщик.Мы можем использовать библиотеку кодеков Commons для Base64 Encoder.Ниже приведен пример:

1. Add Commons Codec library in classpath of your project
2. Add import statement for Base64 Class.

import org.apache.commons.codec.binary.Base64;

3. Encrypt your data

String testString = "Hello World";
byte[] encodedBytes = Base64.encodeBase64(testString.getBytes());
// Get encoded string
String encodedString = new String(encodedBytes);
// Get decoded string back
String decodedString = new String(Base64.decodeBase64(encodedBytes));

После использования библиотеки кодеков Commons вы не должны снова видеть предупреждение выше.

0 голосов
/ 10 июня 2019

Чтобы построить из bullet 5 из превосходного ответа Sahil Muthoo , ниже приведен более глубокий взгляд на исходный код.

По умолчанию метод update просто добавляет входной байтмассив до текущего tempArray абстрактного класса MessageDigestSpi.

Класс MessageDigest расширяет класс MessageDigestSpi.Затем вызывается MessageDigest.update, вызывается метод MessageDigestSpi.engineUpdate, который можно найти при исследовании исходного кода:

MessageDigest.java ( исходный код )

196:   /**
197:    * Updates the digest with the byte.
...
200:    */
201:   public void update(byte input)
202:   {
203:     engineUpdate(input);
204:   }
205: 
206:   /**
207:    * Updates the digest with the bytes from the array starting from the
208:    * specified offset and using the specified length of bytes.
209:    * 
210:    * @param input
211:    *          bytes to update the digest with.
212:    * @param offset
213:    *          the offset to start at.
214:    * @param len
215:    *          length of the data to update with.
216:    */
217:   public void update(byte[] input, int offset, int len)
218:   {
219:     engineUpdate(input, offset, len);
220:   }
...
227:   public void update(byte[] input)
228:   {
229:     engineUpdate(input, 0, input.length);
230:   }
...
238:   public void update (ByteBuffer input)
239:   {
240:     engineUpdate (input);
241:   }

MessageDigestSpi.engineUpdate - это абстрактный метод, который должен быть реализован путем расширения классов, как показано ниже:

MessageDigestSpi.java ( исходный код )

42:    /**
43:     * Updates this {@code MessageDigestSpi} using the given {@code byte}.
44:     *
45:     * @param input
46:     *            the {@code byte} to update this {@code MessageDigestSpi} with.
47:     * @see #engineReset()
48:     */
49:    protected abstract void engineUpdate(byte input);
50:    /**
51:     * Updates this {@code MessageDigestSpi} using the given {@code byte[]}.
52:     *
53:     * @param input
54:     *            the {@code byte} array.
55:     * @param offset
56:     *            the index of the first byte in {@code input} to update from.
57:     * @param len
58:     *            the number of bytes in {@code input} to update from.
59:     * @throws IllegalArgumentException
60:     *             if {@code offset} or {@code len} are not valid in respect to
61:     *             {@code input}.
62:     */
63:    protected abstract void engineUpdate(byte[] input, int offset, int len);
64:    /**
65:     * Updates this {@code MessageDigestSpi} using the given {@code input}.
66:     *
67:     * @param input
68:     *            the {@code ByteBuffer}.
69:     */
70:    protected void engineUpdate(ByteBuffer input) {
71:        if (!input.hasRemaining()) {
72:            return;
73:        }
74:        byte[] tmp;
75:        if (input.hasArray()) {
76:            tmp = input.array();
77:            int offset = input.arrayOffset();
78:            int position = input.position();
79:            int limit = input.limit();
80:            engineUpdate(tmp, offset+position, limit - position);
81:            input.position(limit);
82:        } else {
83:            tmp = new byte[input.limit() - input.position()];
84:            input.get(tmp);
85:            engineUpdate(tmp, 0, tmp.length);
86:        }
87:    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...