MessageDigest 的 update 方法有什么作用以及 BASE64Encoder 的用途是什么?

发布于 2025-01-07 22:14:06 字数 1809 浏览 0 评论 0 原文

以下是加密用户字符串的代码:

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 中的字符串?

该方法 的作用是什么更新MessageDigest类的做什么?即语句 md.update(plainText.getBytes("UTF-8")); 的作用是什么?

什么是 BASE64Encoder 类?我找不到它的 DOC

Following is a code that will encrypts the user String :

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);
      }
}
}

When i compile the code i get the these warnings :

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

Is there any other method to encrypt strings in java ?

What does the method update of class MessageDigest do ? i.e What does the statement md.update(plainText.getBytes("UTF-8")); do ?

What is a BASE64Encoder class ? I couldn't find it's DOC

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

以为你会在 2025-01-14 22:14:06
  1. 首先,您没有执行任何加密。您正在计算输入的单向哈希或摘要。该散列稍后可用于验证消息的完整性。请参阅哈希SHA1消息摘要

  2. Base64 编码 是一种用 ASCII 表示二进制数据的方法。这通常是可取的,因为并非所有数据存储和传输机制都支持原始二进制文件。例如,如果您想通过 http 查询字符串参数传输计算出的摘要,则需要将其编码为 Base64。此外,将原始二进制文件保存或打印到控制台将产生一串奇怪的字符,这些字符可能超出可打印范围,并且还可能从您的 PC 扬声器发出蜂鸣声!

  3. 您使用的 Base64Encoder 来自 sun.misc 包,切勿使用。这是内部 Sun JVM 代码,将来可能可用,也可能不可用。这也解释了为什么您找不到任何 javadoc。

  4. 幸运的是,存在一些免费且开放的 Base64 编码器和解码器。 Apache Commons Codec 是一个广泛使用且稳定的库,其中包含多个编解码器,包括 Base64

  5. md.update(plainText.getBytes("UTF-8")) 更新摘要的输入。调用digest执行最终更新并计算输入的摘要。请参阅 的 javadoc md.digestmd.update

  1. First of all, you're not performing any encryption. You're computing a one-way hash or digest of your input. This hash can be later used to verify the integrity of the message. See Hashing, SHA1 and MessageDigest.

  2. Base64 encoding is a method of representing binary data in ASCII. This is often desirable because not all data storage and transmission mechanisms support raw binary. For example, if you want to transfer your computed digest via an http query string parameter, you'll want to encode it as Base64. Also, saving or printing raw binary to the console will produce a stream of funky characters which may be outside of the printable range, and may also produce beeps from your PC speaker!

  3. The Base64Encoder you're using comes from the sun.misc package and should NEVER be used. This is internal Sun JVM code which may or may not be available in the future. That also explains why you're weren't able to find any javadoc.

  4. Fortunately, several free and open Base64 encoders and decoders exist. Apache Commons Codec is a widely used and stable library which contains several codecs include Base64.

  5. md.update(plainText.getBytes("UTF-8")) updates the input to the digest. Calling digest performs a final update and computes the digest of the input. See javadoc of md.digest and md.update

未蓝澄海的烟 2025-01-14 22:14:06

为了构建Sahil Muthoo 出色答案的第 5 条,下面是对源代码的更深入研究。

默认情况下,update 方法只是将输入字节数组附加到 MessageDigestSpi 抽象类的当前 tempArray 中。

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:    }

To build off of bullet 5 from Sahil Muthoo's excellent answer, below is an deeper look into the source code.

By default, the update method simply appends the input byte array to the current tempArray of the MessageDigestSpi abstract class.

The MessageDigest class extends the MessageDigestSpi class. Then MessageDigest.update is called the method MessageDigestSpi.engineUpdate is called, which can be found from investigating the source code:

MessageDigest.java (source code)

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 is an abstract method that must be implemented by extending classes as seen below:

MessageDigestSpi.java (source code)

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:    }
迷荒 2025-01-14 22:14:06

虽然这里的旧帖子是更新的答案。 Java 8 的 Base64。

Java 8 Base64 文档

While old post here is an updated answer. Java 8's Base64.

Java 8 Base64 Documents

没有伤那来痛 2025-01-14 22:14:06

对于Base64加密和解密,这个警告明确表示不鼓励使用Sun的Base64Encoder实现,并警告该实现可能会在未来版本中删除,我们能做的就是切换到Base64编码器的其他实现。我们可以使用 Commons Codec 库 进行 Base64 编码器。以下是一个示例:

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 编解码器库后,您不应再看到上述警告。

For Base64 encryption and decryption this warning clearly says that it does not encourage the use of Sun implementation of Base64Encoder and gives a warning that the implementation may be removed in future releases, what we can do is to switch to other implementation of Base64 encoder. We can use Commons Codec library for Base64 Encoder. Following is an example:

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

After using Commons codec library, you should not see above warning again.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文