java - 如何逐字节将 SHA-1 应用于大的十六进制数?

标签 java sha

我正在尝试创建一个程序,使我能够将 MEID(长度为 14 的十六进制数)转换为伪 ESN(长度为 8 的十六进制数)。从 MEID 获取 pESN 的方法在理论上相当简单。例如,给定 MEID 0xA0000000002329,要生成 pESN,需要将 SHA-1 应用于 MEID。 A0000000002329 上的 SHA-1 给出 e3be267a2cd5c861f3c7ea4224df829a3551f1ab。取此结果的最后 6 个十六进制数,并将其附加到 0x80 - 结果为 0x8051F1AB。

现在这是我到目前为止的代码:

public void sha1() throws NoSuchAlgorithmException {

    String hexMEID = "A0000000002329";

    MessageDigest mDigest = MessageDigest.getInstance("SHA1");      
    byte[] b = new BigInteger(hexMEID,16).toByteArray();    

    byte[] result = mDigest.digest(b);
    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < result.length; i++) {
        sb.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1));
    }

    System.out.println(sb.toString());
}

问题是使用这种方法,A0000000002329 上的 SHA-1 给出 6ad447f040941bf43c0693d2b391c6c79fa58320 而不是 e3be267a2cd5c861f3c7ea4224df829a3551f1ab。我在这里做错了什么??

有人给了我一个暗示

The trick is to apply SHA-1 to the number representing the MEID, not the string representing the MEID. You'll need to process it byte-by-byte, so you must give it two hex numbers at a time (since two hex numbers make a byte) and make sure they are interpreted as numbers and not ASCII characters.

如果这些说明是正确的,那么我如何将 SHA-1 逐字节应用于我的十六进制数??

最佳答案

你有一个小问题,这是使用 BigInteger 获取字节数组的结果。由于 MEID 只有 7 个字节长,当您通过 BigInteger 抽取它时,您将得到一个长度为 8 的字节数组,因为 BigInteger 输出包含符号的 exta 字节。当然,这个额外的字节会导致输入的 SHA-1 散列完全不同。你需要把它剥下来。

下面是 HEX MEID 到 ESN 代码的样子:

String hexMEID = "A0000000002329";
MessageDigest mDigest = MessageDigest.getInstance( "SHA1" );

byte[] input = new byte[ 7 ]; // MEIDs are only 7 bytes

// Now copy the bytes from BigInteger skipping the extra byte added by it
System.arraycopy( new BigInteger( hexMEID, 16 ).toByteArray(), 1, input, 0, 7 );

// Get the SHA-1 bytes
byte[] result = mDigest.digest( input );

// Build the SHA-1 String
StringBuilder sb = new StringBuilder();
for ( int i = 0; i < result.length; i++ )
{
    String hex = Integer.toHexString( 0xFF & result[ i ] );
    if ( hex.length() == 1 )
    {
        sb.append( '0' );
    }
    sb.append( hex );
}

String sha1 = sb.toString();
// Grab the last 6 characters of the SHA-1 hash
String lastSix = sha1.substring( sha1.length() - 6 );
// And prepend '80', now you have the ESN
System.out.println( "80" + lastSix );
// Will print 8051f1ab which is exactly what you want

关于java - 如何逐字节将 SHA-1 应用于大的十六进制数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11838825/

相关文章:

java - 如何查找本地IP地址

java crypto SHA512withRSA 不工作 genkeypair

javascript - 如何让 Google Apps 脚本执行 SHA-256 加密?

java - php 的 hmac sha256 实现与 java 的不匹配

java - 是否可以用 Java 编写 "foreach"函数?

java - 如何在 Eclipse 中使用 MiG Layout?

java - 在 Java 中隐藏 swagger UI 中不重要的 getter 方法

rust - 如何将哈希转换为字符串? [复制]

java - 如何使 "MessageDigest SHA-1 and Signature NONEwithRSA"等同于 "Signature SHA1withRSA "

java - Spring 不断返回字符串而不是 jsp/html 内容