Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Was ich suche ist eine Bibliothek, die mir ermöglicht mehrere pro Rechner einmalige(oder fast) Werte abzufragen und daraus dann eine Id zu generieren.(MAX-Adresse, cpu(stepping,modell,ect), grafikkarte) Wichtig hierbei ist, das dies nach einem neuinstall des OS immernoch die selbe ID ist.
Das ganze muss in eine komerzielle Anwendung eingebunden werden.
Bislang habe ich nur Sigar - Hyperic gefunden, welches unter der GPL steht.
Meine Fragen sind jetzt:
a) Kennt jemand alternativen die unter der LGPL oder einen anderen kommerziell kompatiblerenen Licenz stehen.
b) Wenn ich ein Kommandozeilen Tool programmiere, das ich mitsamt Quellcode und GPL veröffentliche, und dieses lediglich über ProcessBuilder anspreche das problem umgehe, und meinen eigenen Code weiterhin behalten darf/nicht veröffentlichen muss.
Falls du das für Lizenztechnische Sachen verwendest, dann würde ich davon absehen.
Das hat man früher so gemacht und heutzutage, wenn die Software auf VMs läuft und dann zwischen Hosts hin und her geschickt wird, dann klappt wieder die hälfte nicht.
In diesem Forum gab es ansonsten mehrere Threads, die das verschlüsseln von Jars behandeln.
Ansonsten bleibt dir ja dann immernoch das Problem, dass man den JavaCode einfach dekompilieren kann und dann austauschen, sehen kann wie ID berechnet wird.
Gruß,
Martin
~~
Eventuell fällt mir was cooles ein: Wenn du eine ID generiert hast e.g. vis UniqueID oder so, dann kannst du die ja einmal exportieren und wenn man die installation neu macht, dann kann man die ID wieder importieren ;D - Aber denke nicht, dass das hilft ^^
Drücken wir es so aus, wer die Id fälscht, schadet sich selber, es ist im intresse des nutzers das die gleich bliebt.
Gibt halt keine hundertprozentige Lösung, außerdem soll ich das so amchen, würde das sonst wohl auch anders lösen.
Wird auch nichts zwischen irgetwas hin und hergeschickt, das ausführen der datei selber klappt problemlos, frage ist halt , ob das probleme von wegen der gpl gibt.
Ich hab mir da mal vor längerer Zeit was gebastelt:
Java:
/**
* Returns an ID identifying the current machine
* @return
* @throws MachineIdException if there is a problem getting the machines id
*/
public static String getMachineId() throws MachineIdException {
String machineId = null;
final String osName = System.getProperty("os.name");
sb = new StringBuffer();
if (osName.contains("Windows")){
logger.debug("on MS Windows");
sb.append("on MS Windows\n");
System.out.println("CU: on Windows");
try {
// get runtime environment and execute child processes
Runtime systemShell = Runtime.getRuntime();
String systemRoot = System.getenv("SystemRoot");
// query registry for windows folder timestamp and volume-serial
String cmd = systemRoot+"/system32/cmd.exe /c \"dir /TC "+systemRoot+"\"";
sb.append("cmd="+cmd+"\n");
Process output = systemShell.exec(cmd);
// open reader to get output from process
BufferedReader br = new BufferedReader (new InputStreamReader(output.getInputStream()));
String line = null;
int step=1;
while((line = br.readLine()) != null ) {
sb.append("line="+line+"\n");
if(step==2) {
machineId=line.trim(); // volume serial
}
// removed due to timezone problems with summertime/wintertime
// if(step==6) {
// machineId+="|"+line.trim(); // windows folder timestamp
// }
step++;
} // display process output
//output.destroy();
if (output.exitValue()!=0) {
String msg = "could not run first part for windows machine id. exit value="+output.exitValue()+", machineId so far="+machineId;
sb.append(msg);
logger.warn(msg);
throw new MachineIdException("could not get machine id (WIN/1)");
}
// query registry for windows guid
cmd = systemRoot+"/system32/cmd.exe /c reg query \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography\" /v MachineGuid";
sb.append("cmd="+cmd+"\n");
output = systemShell.exec(cmd);
// open reader to get output from process
br = new BufferedReader (new InputStreamReader(output.getInputStream()));
line = null;
while((line = br.readLine()) != null ) {
sb.append("line="+line+"\n");
if (line.contains("MachineGuid"))
machineId+="|"+line.trim();
}
//output.destroy();
if (output.exitValue()!=0 && !machineId.contains("MachineGuid")) {
String msg = "could not run second part for windows machine id. exit value="+output.exitValue()+", machineId so far="+machineId;
logger.warn(msg);
throw new MachineIdException("could not get machine id (WIN/2)");
}
// query registry for windows cd-key
cmd = systemRoot+"/system32/cmd.exe /c reg query \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\" /v DigitalProductId";
sb.append("cmd="+cmd+"\n");
//System.out.println("cmd="+cmd);
output = systemShell.exec(cmd);
// open reader to get output from process
br = new BufferedReader (new InputStreamReader(output.getInputStream()));
line = null;
while((line = br.readLine()) != null ) {
sb.append("line="+line+"\n");
if (line.contains("DigitalProductId"))
machineId+="|"+line.trim();
}
//output.destroy();
if (output.exitValue()!=0 && !machineId.contains("DigitalProductId")) {
String msg = "could not run third part for windows machine id. exit value="+output.exitValue()+", machineId so far="+machineId;
logger.warn(msg);
throw new MachineIdException("could not get machine id (WIN/3)");
}
logger.trace("machineId(raw)={}",machineId);
sb.append("machineId(raw)="+machineId+"\n");
} catch (IOException ioe){
logger.error(ioe.getMessage());
throw new MachineIdException("IO-Fehler aufgetreten. Bitte Diagnosebericht senden und im Support-Board melden.");
}
} else if (osName.contains("Mac OS X")) {
logger.debug("on Mac OS X");
sb.append("on Mac OS X\n");
try {
// get runtime environment and execute child process
Runtime systemShell = Runtime.getRuntime();
String cmd="system_profiler SPHardwareDataType";
sb.append("cmd="+cmd+"\n");
Process output = systemShell.exec(cmd);
BufferedReader br = new BufferedReader (new InputStreamReader(output.getInputStream()));
String line;
while((line = br.readLine()) != null ) {
try {
System.out.println("C: reading line ...");
Thread.sleep(100);
} catch (InterruptedException ex) {
}
sb.append("line="+line+"\n");
if (line.contains("Serial")){
machineId=line.trim();
break;
}
}
br.close();
output.destroy();
if (output.exitValue()!=0) {
logger.warn("could not run for macos machine id. exit value={}"+output.exitValue());
throw new MachineIdException("could not get machine id");
}
if (machineId == null){
logger.error("Could not get machine id");
}
logger.trace("machineId(raw)={}", machineId);
sb.append("machineId(raw)="+machineId+"\n");
} catch (IOException ioe){
logger.error(ioe.getMessage());
throw new MachineIdException("IO-Fehler aufgetreten. Bitte Diagnosebericht senden und im Support-Board melden.");
}
} else if (osName.contains("Linux")) {
logger.debug("on Linux");
sb.append("on Linux\n");
System.out.println("CU: on linux");
String rootDisk = "/dev/hda"; // default value
String cmd;
System.out.println("CU: 3");
try {
// get runtime environment and execute child process
Runtime systemShell = Runtime.getRuntime();
// find where "/" is mounted on
cmd = "mount";
sb.append("cmd="+cmd+"\n");
Process output1 = systemShell.exec(cmd);
BufferedReader br1 = new BufferedReader (new InputStreamReader(output1.getInputStream()));
System.out.println("CU: 4");
String rootPartition = null;
String line;
while((line = br1.readLine()) != null ) {
System.out.println("CU: 5");
sb.append("line="+line+"\n");
if (line.contains(" on / type")){
rootPartition = line.split(" ")[0];
}
}
System.out.println("CU: 6");
br1.close();
if (output1.exitValue()!=0) {
System.out.println("CU: 1");
logger.warn("could not run first part for linux machine id. exit value={}"+output1.exitValue());
throw new MachineIdException("could not get machine id (LINUX/1)");
}
System.out.println("CU: step1 done");
// check for sw-raid, i.e. "/dev/md1"
if (rootPartition.substring(0,7).equalsIgnoreCase("/dev/md")){
rootDisk = rootPartition;
} else {
// rootPartition may be /dev/sda6. Now we cut-off the "6", cause we want the disk, not the partition
rootDisk = rootPartition.substring(0, rootPartition.length()-1);
}
System.out.println("CU: 7");
System.out.println("CU: preparing step2");
// now we get the disk's identifier
cmd = "udevinfo -q all -n "+rootDisk;
sb.append("cmd="+cmd+"\n");
Process output2 = systemShell.exec(cmd);
BufferedReader br2 = new BufferedReader (new InputStreamReader(output2.getInputStream()));
System.out.println("CU: 8");
// open reader to get output from process
// We are interested in lines like this:
// S: disk/by-id/ata-SAMSUNG_SP2514N_S08BJ1LP202081
// there can be more than one line, so we concat them
while((line = br2.readLine()) != null ) {
System.out.println("CU: 9");
sb.append("line="+line+"\n");
if (line.contains("S: disk/by-id")){
machineId+=line.trim();
}
}
br2.close();
System.out.println("CU: 10");
if (output2.exitValue()!=0) {
System.out.println("CU: 2");
logger.warn("could not run second part for linux machine id. exit value={}"+output2.exitValue());
throw new MachineIdException("could not get machine id (LINUX/2)");
}
logger.trace("machineId(raw)={}",machineId);
sb.append("machineId(raw)="+machineId+"\n");
System.out.println("CU: step2 done");
} catch (IOException ioe){
if (ioe.getMessage().contains("Cannot run program \"udevinfo\"")) {
sb.append("could not run 1st alternative of 2nd part, try 2nd alternative...");
try {
logger.debug("udevinfo not available, try 'udevadm info' instead");
String line;
cmd = "udevadm info -q all -n "+rootDisk;
sb.append("cmd="+cmd+"\n");
Process output2 = Runtime.getRuntime().exec(cmd);
BufferedReader br2 = new BufferedReader (new InputStreamReader(output2.getInputStream()));
// open reader to get output from process
// We are interested in lines like this:
// S: disk/by-id/ata-SAMSUNG_SP2514N_S08BJ1LP202081
// there can be more than one line, so we concat them
while((line = br2.readLine()) != null ) {
sb.append("line="+line+"\n");
if (line.contains("S: disk/by-id")){
machineId+=line.trim();
}
}
br2.close();
if (output2.exitValue()!=0) {
logger.warn("could not run alternative second part for linux machine id. exit value={}"+output2.exitValue());
throw new MachineIdException("could not get machine id (LINUX/2/2)");
}
} catch (IOException e) {
logger.error(ioe.getMessage());
throw new MachineIdException("IO-Fehler aufgetreten. Bitte Diagnosebericht senden und im Support-Board melden.");
} catch (IllegalThreadStateException e) {
logger.error(e.getMessage());
throw new MachineIdException("IO-Fehler aufgetreten. Bitte Diagnosebericht senden und im Support-Board melden.");
}
} else {
logger.error(ioe.getMessage());
throw new MachineIdException("IO-Fehler aufgetreten. Bitte Diagnosebericht senden und im Support-Board melden.");
}
System.out.println("CU: step2b done");
}
} else {
logger.error("os not supported: {}", osName);
sb.append("os not supported\n");
throw new MachineIdException("os not supported: "+osName);
}
// check if raw-string is "valid"
if (machineId==null || machineId.length()<5) {
logger.warn("Could not get machine id for os '{}'. id(raw)={}", osName, machineId);
sb.append("Could not get machine id for os '"+osName+"'. id(raw)="+machineId+"\n");
throw new MachineIdException("Could not get machine id for os '"+osName+"'.");
}
String result = null;
try {
System.out.println("CU: enc");
result = SimpleSHA1.toSHA1(machineId);
System.out.println("CU: enc done");
} catch (NoSuchAlgorithmException ex) {
logger.error(ex.getMessage());
throw new MachineIdException("NoSuchAlgorithm: "+ex.getMessage());
} catch (UnsupportedEncodingException ex) {
logger.warn(ex.getMessage());
throw new MachineIdException("UnsupportedEncoding: "+ex.getMessage());
}
return result;
}
Abgedeckt hab ich damit die 3 Major-Betriebssysteme. Windows, Linux und MacOSX
Auf der Windowsseite hab ich gleich mehrere Faktoren für die ID Berechnung benutzt:
* Volume Serial der C:\ Partition (ändert sich wenn man die Platte neu formatiert)
* Die MachineGuid aus der Registry. Laut google ist diese GUID schon "ziemlich unique"
* DigitalProductId aus der Registry. Das ist der Windows-Serial-KEY den man für die Installation braucht
Alles zusammen wird in ein String gepackt, den ich dann in einem SHA1 Hash verwandle.
Auf der Linux-Seite: Da nehm ich die ID der Festplatte
Auf der MacOSX Seite: Da ist's am einfachsten. Da gibts eine Hardware-Seriennummer die man abfragen kann
Ganz optimal ist das noch nicht (auch von der Implementierung her). Aber es funktioniert und hat in der Form bisher noch keine Probleme gegeben. Einzige vorraussetzung die diese Implementierung hat:
Hat man ein 64bit OS, muss man eine 64bit JVM benutzen. Will man das nicht, muss man die "reg query" Befehle für die Windows-Seite anpassen (liegt an der "virtualisierung" der Registry in Bezug auf Benutzer und 32/64bit Prozesse)
Hab mich damals auch bewusst gegen die MAC-Adresse entschieden. Laptops z.B. schalten gerne mal unbenutzte Netzwerkdevices aus. Und dann ist die MAC-Adresse nicht mehr zu sehen.
- Alex
p.s. hmm, hab jetzt erste gesehen dass die ID nach einer Neuinstallation noch gleich sein soll. Damit fällt meine Lösung für die Windows-Seite weg... Das einzig "eindeutige" ist dann noch der Windows-Serial-Key :-(
Der teil vom mac ist aber aufjedenfall trotzdem praktisch, wusste garnet das die ne id haben
und bei linux habe ich zumindest einen ansatz (wobei ich den noch erweitern muss, fals mal jemand die festplatte tauscht)
Unter Linux ist es mit dem SysFs eh ziemlich easy an so ziemlich alle Hardwaredaten zu kommen.
Beim MAC reicht in der Tat diese eine ID aus (soweit ich das jetzt gelesen habe).
Windows ist da halt nach wie vor im Nachteil. Da kommt man um native Programmierung fast nicht rum. Aber für meinen Anwendungsfall war die generierte ID ausreichend.