如何在Java中执行MySQL UNHEX()函数
我试图从字符串中获取Java中的MySQL密码哈希,所以我在Google上搜索了一下,发现了MySQL中的Password()是如何工作的:如何在Java中执行MySQL UNHEX()函数,java,mysql,hash,passwords,Java,Mysql,Hash,Passwords,我试图从字符串中获取Java中的MySQL密码哈希,所以我在Google上搜索了一下,发现了MySQL中的Password()是如何工作的: SELECT SHA1(UNHEX(SHA1('test'))); 给出与相同的结果 SELECT PASSWORD('test'); 我接着说 我编写了一个将字符串转换为SHA1散列的方法,该方法非常有效(测试了几个不同的字符串,得到的结果与MySQL中的SHA1(str)相同) 接下来要做的是UNHEX()方法。我现在被卡住了 我目前的方法是: p
SELECT SHA1(UNHEX(SHA1('test')));
给出与相同的结果
SELECT PASSWORD('test');
我接着说
我编写了一个将字符串转换为SHA1散列的方法,该方法非常有效(测试了几个不同的字符串,得到的结果与MySQL中的SHA1(str)相同)
接下来要做的是UNHEX()方法。我现在被卡住了
我目前的方法是:
public static String toMySQLPasswordHash(String str)
{
String hash1 = toSHA1Hash(str);
String unhexedHash1 = new String(DatatypeConverter.parseHexBinary(hash1));
String hash2 = toSHA1Hash(unhexedHash1);
String passwordHash = "*" + hash2.toUpperCase();
return passwordHash;
}
我的“toSHA1Hash”方法:
我不喜欢使用任何外部软件包,所以请帮助我仅使用JDK 1.8.0_40来实现这一点。因此,5年后,我正在编辑我自己对这个问题的答案,因为当时我并不知道我真正在做什么。答案是有效的,但不是最优的 1.实际问题:“如何在Java中执行MySQL UNHEX()函数?” 1.1 MySQL中的UNHEX()函数实际上做什么 这个问题的答案很简单。它接受并将其转换为二进制对象 请记住:十六进制字符串只是将字节表示为文本的许多方法之一。这句话很简单,这就是这个问题的答案——我们只需将这个字符串转换成
字节[]
有了这些知识,我们就有了答案,多年前就在这里:
简言之:
//这是MySQL中UNHEX()函数的Java等价物
公共静态字节[]hexStringToByteArray(字符串s){
int len=s.length();
字节[]数据=新字节[len/2];
对于(int i=0;i
jakarta.xml.bind
,前缀为文字*
2.2分解它
2.2.1 SHA1散列
要构建任何输入的SHA1哈希,我们可以使用Java中的MessageDigest
类
import java.security.MessageDigest;
导入java.security.NoSuchAlgorithmException;
公共静态字节[]摘要(字符串算法,字节[]数据)抛出NoSuchAlgorithmException{
返回MessageDigest.getInstance(算法).digest(数据);
}
公共静态字节[]sha1(字节[]数据)引发NoSuchAlgorithmException{
返回摘要(“SHA-1”,数据);
}
2.2.2 SHA1哈希的SHA1哈希
publicstaticbyte[]mysqlPasswordHash(byte[]data)抛出NoSuchAlgorithmException{
//使用2.2.1中说明的方法两次
返回sha1(sha1(数据));
}
2.2.3构建一个字节[]
这与我之前描述的UNHEX()函数相反,当我问这个问题时已经有了很多答案。请参阅:
private static final byte[]HEX_ARRAY=“0123456789ABCDEF”.getBytes(StandardCharsets.UTF_8);
公共静态字符串bytesToHex(字节[]字节){
最终字节[]hexChars=新字节[bytes.length*2];
对于(int j=0;j>>4];
hexChars[j*2+1]=十六进制数组[v&0x0F];
}
返回新字符串(hexChars、StandardCharsets.UTF_8);
}
或者,如果您有可用的DataTypeConverter
:
公共静态字符串bytesToHex(字节[]字节){
返回DatatypeConverter.printHexBinary(字节);
}
2.2.4相当于MySQL密码功能
如果您添加了前面步骤中描述的方法,那么Java中的MySQL密码实现的工作原理如下:
public静态字符串mysqlPasswordHashString(字符串密码,Charset Charset)抛出NoSuchAlgorithmException{
返回“*”+bytesToHex(mysqlPasswordHash(password.getBytes(charset));
}
2.3调用该方法
要调用该方法,必须提供一个java.nio.charset.charset
。要获得与在MySQL数据库上运行该方法相同的结果,必须确定MySQL的默认字符集是什么
假设您的MySQL使用UTF-8:
publicstaticvoidmain(字符串[]args)引发异常{
最后一个字符串mysqlPasswordHash=mysqlPasswordHashString(“helloworld”,StandardCharsets.UTF_8);
System.out.println(mysqlPasswordHash);
}
这没有帮助吗?我正在使用MessageDigist创建我的SHA1哈希,它工作得非常好。我一直无法退出SHA1哈希。也许你想编辑你的帖子并询问如何实现UNHEX()函数……你不应该将二进制数据存储在字符串中(unhexedHash1
)!改用字节数组。首先不要对其进行十六进制运算。运行sha1
,获取二进制数组,再次运行sha1
,然后对最终结果进行十六进制运算。
public static String toSHA1Hash(String str)
{
MessageDigest md = null;
try
{
md = MessageDigest.getInstance("SHA-1");
}
catch (NoSuchAlgorithmException e)
{
Logger.WriteLog(e.toString());
}
if (md == null)
return null;
md.reset();
md.update(str.getBytes());
byte[] byteData = md.digest();
StringBuilder sb = new StringBuilder();
for (byte currByte : byteData)
sb.append(Integer.toString((currByte & 0xff) + 0x100, 16).substring(1));
return sb.toString();
}