【问题标题】:Make SHA1 encryption on Android?在 Android 上进行 SHA1 加密?
【发布时间】:2011-08-11 01:13:50
【问题描述】:

你能建议我如何使用 SHA1 算法加密字符串吗? 我已经搜索过了。但没有运气。

提前致谢。

【问题讨论】:

  • SHA1 不是加密算法,而是哈希算法。一旦你散列了你的消息,就不可能“去散列”它。只是让你知道。更多信息在这里:en.wikipedia.org/wiki/Hash_algorithm.
  • 恕我直言,仅仅对字符串进行一次散列是不够的。考虑用随机种子对字符串进行加盐处理,并“递归”地对加盐字符串进行至少 1000 次哈希处理。然后,您需要存储随机种子。
  • 一种更简单的 SHA-1 方法:(根据评论者的建议更新,也使用了更高效的字节->字符串算法)见此链接stackoverflow.com/questions/5980658/…

标签: java android encryption sha1


【解决方案1】:

这是我在搜索 sha1 算法实现时发现的两种方法:

private static String convertToHex(byte[] data) { 
    StringBuffer buf = new StringBuffer();
    int length = data.length;
    for(int i = 0; i < length; ++i) { 
        int halfbyte = (data[i] >>> 4) & 0x0F;
        int two_halfs = 0;
        do { 
            if((0 <= halfbyte) && (halfbyte <= 9)) 
                buf.append((char) ('0' + halfbyte));
            else 
                buf.append((char) ('a' + (halfbyte - 10)));
            halfbyte = data[i] & 0x0F;
        }
        while(++two_halfs < 1);
    } 
    return buf.toString();
}

public static String SHA1(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException  { 
    MessageDigest md = MessageDigest.getInstance("SHA-1");
    byte[] sha1hash = new byte[40];
    md.update(text.getBytes("iso-8859-1"), 0, text.length());
    sha1hash = md.digest();
    return convertToHex(sha1hash);
} 

使用SHA1 方法获取您的sha1 字符串。我尚未确认这确实是 sha1,但它适用于我的应用程序。

【讨论】:

  • 你的缩进看起来有点不一致,所以我让它更一致。如果你不喜欢它,只需回滚。 :)
  • 另外请记住,byte[] 是一种比十六进制字符串更紧凑的格式,因此在需要将数据呈现给用户之前,将其存储为 byte[] 可能更有效,在这种情况下,用户需要十六进制。
  • 关于缩进.. 我只是从 Eclipse 复制和粘贴。复制/粘贴后,我似乎无法将其转换为良好的格式。难道我做错了什么?哈
  • 问题是这个 convertToHex 方法正在跳过结果中的所有其他转换字符。例如,“祝你有美好的一天!”应该是 56cb5d30886e7715f9861220e940758abcbe5473 但是 5c538671f812e478bb57。
  • 从 byte[] 数组转换为十六进制的工作方法发布在forums.xkcd.com/viewtopic.php?f=11&t=16666&p=553936
【解决方案2】:

binnyb 的convertToHex 方法无法正常工作。对我有用的更正确的是:

private static String convertToHex(byte[] data) { 
    StringBuffer buf = new StringBuffer();
    for (int i = 0; i < data.length; i++) { 
        int halfbyte = (data[i] >>> 4) & 0x0F;
        int two_halfs = 0;
        do { 
            if ((0 <= halfbyte) && (halfbyte <= 9)) {
                buf.append((char) ('0' + halfbyte));
            }
            else {
                buf.append((char) ('a' + (halfbyte - 10)));
            }
            halfbyte = data[i] & 0x0F;
        } while(two_halfs++ < 1);
    } 
    return buf.toString();
} 


public static String SHA1(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException  { 
    MessageDigest md = MessageDigest.getInstance("SHA-1");
    byte[] sha1hash = new byte[40];
    md.update(text.getBytes("iso-8859-1"), 0, text.length());
    sha1hash = md.digest();
    return convertToHex(sha1hash);
} 

使用SHA1 方法获取您的sha1 字符串。

更新:提供完整答案

【讨论】:

  • 你简直太棒了
【解决方案3】:

binnyb 让我走上了正轨,但我在这里找到了一些更容易理解的代码: http://www.coderanch.com/t/526487/java/java/Java-Byte-Hex-String

private static String convertToHex(byte[] data) {
    StringBuilder sb = new StringBuilder(data.length * 2);

    Formatter fmt = new Formatter(sb);
    for (byte b : data) {
        fmt.format("%02x", b);
    }

    return sb.toString();
}

【讨论】:

    【解决方案4】:

    我之前回答过这个问题 (How to SHA1 hash a string in Android?),但它也适合这里:

    Android 带有 Apache 的 Commons Codec,因此您可以简单地使用以下行来创建 SHA-1 十六进制字符串:

    String myHexHash = DigestUtils.shaHex(myFancyInput);
    

    这是您在 Android 4 中默认使用的旧方法。新版本的 DigestUtils 带来了各种风格的 shaHex() 方法,例如 sha256Hex(),并且还使用不同的参数类型重载了这些方法。

    当然,DigestUtils 和 Commons Codec 的其余部分中还有更多功能。看看吧。

    http://commons.apache.org/proper/commons-codec//javadocs/api-release/org/apache/commons/codec/digest/DigestUtils.html

    编辑:

    如果你得到一个 ClassNotFoundError ,你必须在 Maven 中显式添加 commons-codec 作为依赖项(即使它应该与 Android 作为传递依赖项),例如:

        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.7</version>
        </dependency>
    

    此外,您必须将调用更改为:

    String myHexHash = new String(Hex.encodeHex(DigestUtils.sha512(myFancyInput)));
    

    (我的猜测是,这可能是由于 Android VM 中的 ClassLoader 问题(类名冲突) - 这实际上证明了 commons-codec 类已经存在......)

    另请参阅: https://stackoverflow.com/a/9284092/621690

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-03
      • 2012-06-26
      • 1970-01-01
      • 2017-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多