我实现了jar文件的这个例子,它检查它自己的校验和:
File currentJavaJarFile = new File(MainApp.class.getProtectionDomain().getCodeSource().getLocation().getPath());
String jarFile = currentJavaJarFile.getAbsolutePath();// + "jarChecksumTest-1.0.jar";
byte[] data = Files.readAllBytes(Paths.get(jarFile));
MessageDigest complete = MessageDigest.getInstance(data);
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(complete.toString().getBytes());
byte byteData[] = md.digest();
// convert the byte to hex format
StringBuilder sb = new StringBuilder();
for (int i = 0; i < byteData.length; i++)
{
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
}
if ("L9ThxnotKPzthJ7hu3bnORuT6xI=".equals(sb.toString()))
{
System.out.println("Success!!!");
}
然后我运行文件我得到这条消息:
Caused by: java.security.NoSuchAlgorithmException: D:\.....\target\jarChecksumTest-1.0.jar MessageDigest not available
我如何解决这个问题?
答案 0 :(得分:2)
MessageDigest.getInstance()
接受一个字符串参数,即您希望在该消息摘要上使用的算法,例如SHA-256
。使用文件路径创建MessageDigest
毫无意义 - Java会尝试将其视为算法,查找与路径同名的算法,然后在找不到路径时抛出异常。
您的更新会让事情变得更糟 - 您现在正在传递流而不是String
!您正确地创建了MessageDigest md
,但名为complete
的是无意义的。
我认为你要做的是将文件中的字节转换为字节数组?在这种情况下(从Java 7开始),你可以这样做:
String jarFile = currentJavaJarFile.getAbsolutePath();
byte[] data = Files.readAllBytes(Paths.get(jarFile));
(如果您没有运行Java 7,请参阅here以了解其他一些可以正常工作的方法。)然后,文件的字节将存储在data
中(这样您就可以调用md.update(data)
,然后像以前一样处理摘要。
答案 1 :(得分:2)
试试这段代码,运行正常。您可以选择任何算法,无论是SHA / MD5
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class Checksum
{
public static void main(String ar[])
{
File currentJavaJarFile = new File(Checksum.class.getProtectionDomain().getCodeSource().getLocation().getPath());
String filepath = currentJavaJarFile.getAbsolutePath();
StringBuilder sb = new StringBuilder();
try
{
MessageDigest md = MessageDigest.getInstance("SHA-256");// MD5
FileInputStream fis = new FileInputStream(filepath);
byte[] dataBytes = new byte[1024];
int nread = 0;
while((nread = fis.read(dataBytes)) != -1)
md.update(dataBytes, 0, nread);
byte[] mdbytes = md.digest();
for(int i=0; i<mdbytes.length; i++)
sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100 , 16).substring(1));
}
catch(NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch(IOException e)
{
e.printStackTrace();
}
System.out.println("Checksum: "+sb);
}
}