Programing

SHA1에 Java 문자열

crosscheck 2020. 6. 15. 21:44
반응형

SHA1에 Java 문자열


Java에서 간단한 String to SHA1 변환기를 만들려고하는데 이것이 내가 가진 것입니다 ...

public static String toSHA1(byte[] convertme) {
    MessageDigest md = null;
    try {
        md = MessageDigest.getInstance("SHA-1");
    }
    catch(NoSuchAlgorithmException e) {
        e.printStackTrace();
    } 
    return new String(md.digest(convertme));
}

나는 그것을 통과하면 toSHA1("password".getBytes()), 내가 얻을 [�a�ɹ??�%l�3~��.내가 아마 UTF-8 같은 간단한 인코딩 수정 알고,하지만 누군가는 내가 어떤 원하는 것을 얻기 위해 무엇을해야하는지 말해 줄 수 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8? 아니면 내가 완전히 잘못하고 있습니까?


UPDATE
당신은 사용할 수 있습니다 아파치 코 몬즈 코덱 당신을 위해이 일을 할 (버전 1.7+).

DigestUtils.sha1Hex (stringToConvertToSHexRepresentation)

이 제안에 대해 @ Jon Onstott 에게 감사합니다 .


이전 답변
바이트 배열을 16 진 문자열로 변환하십시오. 레알의 방법은 방법을 알려줍니다 .

return byteArrayToHexString(md.digest(convertme))

(Real의 How To에서 복사)

public static String byteArrayToHexString(byte[] b) {
  String result = "";
  for (int i=0; i < b.length; i++) {
    result +=
          Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 );
  }
  return result;
}

BTW, Base64를 사용하여 더 간결하게 표현할 수 있습니다. Apache Commons Codec API 1.4 는 모든 고통을 없애기위한 훌륭한 유틸리티입니다. 여기를 참조하십시오


이것은 문자열을 sha1로 변환하는 솔루션입니다. 내 안드로이드 앱에서 잘 작동합니다.

private static String encryptPassword(String password)
{
    String sha1 = "";
    try
    {
        MessageDigest crypt = MessageDigest.getInstance("SHA-1");
        crypt.reset();
        crypt.update(password.getBytes("UTF-8"));
        sha1 = byteToHex(crypt.digest());
    }
    catch(NoSuchAlgorithmException e)
    {
        e.printStackTrace();
    }
    catch(UnsupportedEncodingException e)
    {
        e.printStackTrace();
    }
    return sha1;
}

private static String byteToHex(final byte[] hash)
{
    Formatter formatter = new Formatter();
    for (byte b : hash)
    {
        formatter.format("%02x", b);
    }
    String result = formatter.toString();
    formatter.close();
    return result;
}

사용 구아바 해싱 클래스를 :

Hashing.sha1().hashString( "password", Charsets.UTF_8 ).toString()

SHA-1 (및 기타 모든 해싱 알고리즘)은 이진 데이터를 반환합니다. 그것은 (자바에서)을 생성한다는 것을 의미합니다 byte[]. byte배열은 않습니다 하지 당신이 단순히으로 바꿀 수 없음을 의미합니다 특정 문자를 나타냅니다 String당신이했던 것처럼합니다.

이 필요한 경우 로 표현할 수있는 방식으로 String형식을 지정해야 byte[]합니다 String(그렇지 않으면 byte[]주변을 유지하십시오 ).

Two common ways of representing arbitrary byte[] as printable characters are BASE64 or simple hex-Strings (i.e. representing each byte by two hexadecimal digits). It looks like you're trying to produce a hex-String.

There's also another pitfall: if you want to get the SHA-1 of a Java String, then you need to convert that String to a byte[] first (as the input of SHA-1 is a byte[] as well). If you simply use myString.getBytes() as you showed, then it will use the platform default encoding and as such will be dependent on the environment you run it in (for example it could return different data based on the language/locale setting of your OS).

A better solution is to specify the encoding to use for the String-to-byte[] conversion like this: myString.getBytes("UTF-8"). Choosing UTF-8 (or another encoding that can represent every Unicode character) is the safest choice here.


This is a simple solution that can be used when converting a string to a hex format:

private static String encryptPassword(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {

    MessageDigest crypt = MessageDigest.getInstance("SHA-1");
    crypt.reset();
    crypt.update(password.getBytes("UTF-8"));

    return new BigInteger(1, crypt.digest()).toString(16);
}

Just use the apache commons codec library. They have a utility class called DigestUtils

No need to get into details.


As mentioned before use apache commons codec. It's recommended by Spring guys as well (see DigestUtils in Spring doc). E.g.:

DigestUtils.sha1Hex(b);

Definitely wouldn't use the top rated answer here.


It is not printing correctly because you need to use Base64 encoding. With Java 8 you can encode using Base64 encoder class.

public static String toSHA1(byte[] convertme) {
    md = MessageDigest.getInstance("SHA-1");
    return Base64.getEncoder().encodeToString((md.digest(convertme));
}

Result

This will give you your expected output of 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8


Base 64 Representation of SHA1 Hash:

String hashedVal = Base64.getEncoder().encodeToString(DigestUtils.sha1(stringValue.getBytes(Charset.forName("UTF-8"))));

Message Digest (hash) is byte[] in byte[] out

A message digest is defined as a function that takes a raw byte array and returns a raw byte array (aka byte[]). For example SHA-1 (Secure Hash Algorithm 1) has a digest size of 160 bit or 20 byte. Raw byte arrays cannot usually be interpreted as character encodings like UTF-8, because not every byte in every order is an legal that encoding. So converting them to a String with:

new String(md.digest(subject), StandardCharsets.UTF_8)

might create some illegal sequences or has code-pointers to undefined Unicode mappings:

[�a�ɹ??�%l�3~��.

Binary-to-text Encoding

For that binary-to-text encoding is used. With hashes, the one that is used most is the HEX encoding or Base16. Basically a byte can have the value from 0 to 255 (or -128 to 127 signed) which is equivalent to the HEX representation of 0x00-0xFF. Therefore hex will double the required length of the output, that means a 20 byte output will create a 40 character long hex string, e.g.:

2fd4e1c67a2d28fced849ee1bb76e7391b93eb12

Note that it is not required to use hex encoding. You could also use something like base64. Hex is often preferred because it is easier readable by humans and has a defined output length without the need for padding.

You can convert a byte array to hex with JDK functionality alone:

new BigInteger(1, token).toString(16)

Note however that BigInteger will interpret given byte array as number and not as a byte string. That means leading zeros will not be outputted and the resulting string may be shorter than 40 chars.

Using Libraries to Encode to HEX

You could now copy and paste an untested byte-to-hex method from Stack Overflow or use massive dependencies like Guava.

To have a go-to solution for most byte related issues I implemented a utility to handle these cases: bytes-java (Github)

To convert your message digest byte array you could just do

String hex = Bytes.wrap(md.digest(subject)).encodeHex();

or you could just use the built-in hash feature

String hex =  Bytes.from(subject).hashSha1().encodeHex();

The reason this doesn't work is that when you call String(md.digest(convertme)), you are telling Java to interpret a sequence of encrypted bytes as a String. What you want is to convert the bytes into hexadecimal characters.


Convert byte array to hex string.

public static String toSHA1(byte[] convertme) {
    final char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();
    MessageDigest md = null;
    try {
        md = MessageDigest.getInstance("SHA-1");
    }
    catch(NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    byte[] buf = md.digest(convertme);
    char[] chars = new char[2 * buf.length];
    for (int i = 0; i < buf.length; ++i) {
        chars[2 * i] = HEX_CHARS[(buf[i] & 0xF0) >>> 4];
        chars[2 * i + 1] = HEX_CHARS[buf[i] & 0x0F];
    }
    return new String(chars);
}

참고URL : https://stackoverflow.com/questions/4895523/java-string-to-sha1

반응형