Entropie sicherstellen...

X

Xyz1

Gast
Hallo, könnt ihr mir helfen? Es soll ein wirklich sicherer HASH berechnet werden abhängig von den Mausbewegungen in einem JPanel. Folgendes JFrame habe ich dafür erstellt:
Java:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Point;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class En {

	public En() {
		final JPanel p1 = new JPanel();
		JPanel p2 = new JPanel(new GridLayout(2, 1));
		final JProgressBar b1 = new JProgressBar();
		final JTextField f2 = new JTextField();
		p2.add(b1);
		p2.add(f2);
		JFrame f1 = new JFrame();
		f1.setLayout(new BorderLayout());
		f1.add(p1, BorderLayout.CENTER);
		f1.add(p2, BorderLayout.SOUTH);
		f1.setSize(800, 800);
		f1.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		f1.setVisible(true);

		new Timer().schedule(new TimerTask() {
			private ArrayList<Point> ps = new ArrayList<Point>();

			@Override
			public void run() {
				Point mousePosition = p1.getMousePosition();
				if (mousePosition != null && (ps.isEmpty() || !ps.get(ps.size() - 1).equals(mousePosition))) {
					ps.add(mousePosition);
					try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
						for (Point point : ps) {
							bos.write(Integer.toString(point.hashCode()).getBytes(StandardCharsets.UTF_8));
						}
						bos.flush();
						MessageDigest md = MessageDigest.getInstance("SHA-256");
						byte[] digest = md.digest(bos.toByteArray());
						StringBuilder sha256 = new StringBuilder(new BigInteger(1, digest).toString(16));
						while (sha256.length() < 32) {
							sha256.insert(0, '0');
						}
						b1.setValue((int) ((bos.size() < 5000 ? bos.size() : 5000) / 50.0));
						f2.setText(sha256.toString());
					} catch (IOException | NoSuchAlgorithmException e1) {
						e1.printStackTrace();
					}
				}
			}
		}, 0, 100);
	}

	public static void main(String[] args) {
		new En();
	}
}

Der Output ist zum Beispiel: bdafdc5be7b2ae116518abd9977bfbd31519bf823e8471c0fbc8870b6d6f2c9b

und mit der Umwandlung von Mouse Positions in byte Arrays bin ich noch nicht ganz d'accord: Integer.toString(point.hashCode()).getBytes(StandardCharsets.UTF_8) . Kennt ihr einen besseren Weg? Danke.
 
X

Xyz1

Gast
Update: Vielleicht wäre das besser:
Java:
int hashCode = point.hashCode();
bos.write(ByteBuffer.allocate(4).putInt(hashCode).array());

Ich habe nämlich "den Eindruck", dass bei der Umwandlung zu String und dann zu byte[] "Entropie verloren geht"... Lässt sich das vielleicht beweisen?
 

White_Fox

Top Contributor
Naja, Mausbewegungen sind aber nur dann ein halbwegs sicherer Zufallsgenerator, solange tatsächlich ein Mensch vor dem Rechner sitzt. Wenn jemand hinter deine Idee kommt, wehe wenn dein Programm die virtuellen Mauspositionen eines Skripts vorgesetzt bekommt...
 

mihe7

Top Contributor
Was verstehst du denn nicht? Die Mauspositionen stellen die Entropie sicher. (da sie mehr oder weniger zufällig erfolgen und fast nicht nachgestellt werden können)
Die Entropie wovon? Die Hashfunktion ist ja nur eine Einwegfunktion, die zu einem gegebenen Wert ebenen einen Hashwert liefert und Secure Hash Algorithm (SHA) heißt ja auch nicht ohne Grund so. Die Frage ist: was willst Du denn mit einem Hashwert anfangen, der über einen Zufallswert erzeugt wurde?
 

LimDul

Top Contributor
Was soll die dumme Antwort? Eine Hashfunktion stellt sicher, dass vom Hash nicht der Seed berechnet werden kann.


Genau so ist es.
Und was fängst du mit dem Seed und was mit dem Hash an?

Ein Hash ist nur sinnvoll, wenn man später verifizieren will, dass der Ursprungswert nicht geändert wurde. Mir ist der Anwendungsfall noch nicht ganz klar, den du hast. Entweder du willst den Seed nachher als Eingabe für eine Random-Funktion verwenden - dann brauchst du den Hash aber nicht.
Oder du willst den Hash als Eingabe für eine Random-Funktion verwenden - dann hättest du aber auch gleich den Seed nehmen können.
 
X

Xyz1

Gast
Ist es nun richtig programmiert oder nicht?

Oder du willst den Hash als Eingabe für eine Random-Funktion verwenden - dann hättest du aber auch gleich den Seed nehmen können
Das Problem ist dass der Seed in seiner anfänglichen Form zu lang ist (ca 500 Mauspositionen), mit SHA256 möchte ich diesen "komprimieren".

Den SHA256 könnte man zum Beispiel auch als "sicheren" Salt verwenden.
 

mihe7

Top Contributor
Den SHA256 könnte man zum Beispiel auch als "sicheren" Salt verwenden.
Genauso gut könntest Du dafür auch eine x-beliebige UUID oder sonst irgendwas verwenden, da das Salt eh in der DB steht.

Der Trick ist, nicht einmal sondern tausendfach zu Hashen, um den zeitlichen Aufwand in die Höhe zu treiben. So stört ein Passwortvergleich von 200 ms beim Login nicht - beim Knacken schon.

Das Problem ist dass der Seed in seiner anfänglichen Form zu lang ist (ca 500 Mauspositionen), mit SHA256 möchte ich diesen "komprimieren".
Ja, Du willst halt einen Hash über die 500 Positionen erstellen :) Code sieht auf den ersten Blick ok aus, hab aber nicht getestet.
 
X

Xyz1

Gast
Na dann teste mal. ;)
Java:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Point;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class En {

	public En() {
		final JPanel p1 = new JPanel();
		JPanel p2 = new JPanel(new GridLayout(2, 1));
		final JProgressBar b1 = new JProgressBar();
		final JTextField f2 = new JTextField();
		p2.add(b1);
		p2.add(f2);
		JFrame f1 = new JFrame();
		f1.setLayout(new BorderLayout());
		f1.add(p1, BorderLayout.CENTER);
		f1.add(p2, BorderLayout.SOUTH);
		f1.setSize(800, 800);
		f1.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		f1.setVisible(true);

		new Timer().schedule(new TimerTask() {
			private ArrayList<Point> ps = new ArrayList<Point>();

			@Override
			public void run() {
				Point mousePosition = p1.getMousePosition();
				if (mousePosition != null && (ps.isEmpty() || !ps.get(ps.size() - 1).equals(mousePosition))) {
					ps.add(mousePosition);
					try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
						for (Point point : ps) {
							int hashCode = point.hashCode();
							bos.write(ByteBuffer.allocate(4).putInt(hashCode).array());
						}
						bos.flush();
						MessageDigest md = MessageDigest.getInstance("SHA-256");
						byte[] digest = md.digest(bos.toByteArray());
						StringBuilder sha256 = new StringBuilder(new BigInteger(1, digest).toString(16));
						while (sha256.length() < 32) {
							sha256.insert(0, '0');
						}
						b1.setValue((int) ((bos.size() < 5000 ? bos.size() : 5000) / 50.0));
						f2.setText(sha256.toString());
					} catch (IOException | NoSuchAlgorithmException e1) {
						e1.printStackTrace();
					}
				}
			}
		}, 0, 100);
	}

	public static void main(String[] args) {
		new En();
	}
}
 
X

Xyz1

Gast
Teste nochmal, ich habe noch einen Stop Button hinzugefügt und sha256.length() < 32 war i-wie blödsinnig. :D
Java:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Semaphore;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class En {
	private final Semaphore SEM = new Semaphore(1);
	private ArrayList<Point> ps = new ArrayList<Point>();
	private String sha256 = "";

	public En() {
		final JPanel p1 = new JPanel();
		final JProgressBar b1 = new JProgressBar();
		final JTextField f2 = new JTextField();
		JButton b2 = new JButton("Stop");
		JPanel p2 = new JPanel(new GridLayout(2, 1));
		JPanel p3 = new JPanel(new BorderLayout());
		p3.add(f2, BorderLayout.CENTER);
		p3.add(b2, BorderLayout.EAST);
		p2.add(b1);
		p2.add(p3);
		JFrame f1 = new JFrame();
		f1.setLayout(new BorderLayout());
		f1.add(p1, BorderLayout.CENTER);
		f1.add(p2, BorderLayout.SOUTH);
		f1.setSize(800, 800);
		f1.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		f1.setVisible(true);

		final Timer timer = new Timer();
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				try {
					SEM.acquire();
					Point mousePosition = p1.getMousePosition();
					if (mousePosition != null && (ps.isEmpty() || !ps.get(ps.size() - 1).equals(mousePosition))) {
						ps.add(mousePosition);
						try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
							for (Point point : ps) {
								int hashCode = point.hashCode();
								bos.write(ByteBuffer.allocate(4).putInt(hashCode).array());
							}
							bos.flush();
							MessageDigest md = MessageDigest.getInstance("SHA-256");
							byte[] digest = md.digest(bos.toByteArray());
							StringBuilder b = new StringBuilder(new BigInteger(1, digest).toString(16));
							while (b.length() < 64) {
								b.insert(0, '0');
							}
							sha256 = b.toString();
							b1.setValue((int) ((bos.size() < 5000 ? bos.size() : 5000) / 50.0));
							f2.setText(sha256);
						} catch (IOException | NoSuchAlgorithmException e1) {
							e1.printStackTrace();
						}
					}
					SEM.release();
				} catch (InterruptedException e2) {
					e2.printStackTrace();
				}
			}
		}, 0, 100);

		b2.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				timer.cancel();
				try {
					SEM.acquire();
					System.out.println(ps.size());
					System.out.println(sha256);
					SEM.release();
				} catch (InterruptedException e2) {
					e2.printStackTrace();
				}
			}
		});
	}

	public static void main(String[] args) {
		new En();
	}
}
 
X

Xyz1

Gast
Bitte jetzt noch-mal testen, ich hatte die Semaphore falsch verwendet, es hätte eine Int...Ex auftreten können... und ich habe den Algorithmus geändert, auf hashCode wird jetzt verzichtet und es wird Zufall eingesetzt, zudem ich habe ich Kommentare hinzugefügt.

Java:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Semaphore;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class En {
	private final Semaphore SEM = new Semaphore(1);
	private ArrayList<Point> ps = new ArrayList<Point>();
	private String sha256 = "";

	public En() {
		final JPanel p1 = new JPanel();
		final JProgressBar b1 = new JProgressBar();
		final JTextField f2 = new JTextField();
		JButton b2 = new JButton("Stop");
		JPanel p2 = new JPanel(new GridLayout(2, 1));
		JPanel p3 = new JPanel(new BorderLayout());
		p3.add(f2, BorderLayout.CENTER);
		p3.add(b2, BorderLayout.EAST);
		p2.add(b1);
		p2.add(p3);
		JFrame f1 = new JFrame();
		f1.setLayout(new BorderLayout());
		f1.add(p1, BorderLayout.CENTER);
		f1.add(p2, BorderLayout.SOUTH);
		f1.setSize(800, 800);
		f1.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		f1.setVisible(true);

		final Timer timer = new Timer();
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				// we have to use a double try block...
				try {
					SEM.acquire();
					try {
						Point mousePosition = p1.getMousePosition();
						if (mousePosition != null && (ps.isEmpty() || !ps.get(ps.size() - 1).equals(mousePosition))) {
							// new position recognized
							ps.add(mousePosition);
							// capture all positions
							ArrayList<Integer> l = new ArrayList<Integer>();
							for (Point point : ps) {
								l.add(point.x);
								l.add(point.y);
							}
							// shuffle all positions
							Collections.shuffle(l);
							// convert all position into a ByteBuffer
							ByteBuffer bb = ByteBuffer.allocate(l.size() * 4);
							for (Integer in : l) {
								bb.putInt(in);
							}
							// start digesting with Sha256
							MessageDigest md = MessageDigest.getInstance("SHA-256");
							byte[] digest = md.digest(bb.array());
							StringBuilder b = new StringBuilder(new BigInteger(1, digest).toString(16));
							// extend the resulting String
							while (b.length() < 64) {
								b.insert(0, '0');
							}
							// set the attributes
							sha256 = b.toString();
							b1.setValue((int) ((bb.position() < 2500 ? bb.position() : 2500) / 25.0));
							f2.setText(sha256);
							// success
						}
					} finally {
						// if an InterruptedException occurs
						SEM.release();
					}
				} catch (InterruptedException | NoSuchAlgorithmException e1) {
					e1.printStackTrace();
				}
			}
		}, 0, 100);

		b2.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				timer.cancel();
				try {
					SEM.acquire();
					try {
						System.out.println(ps.size());
						System.out.println(sha256);
					} finally {
						SEM.release();
					}
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
			}
		});
	}

	public static void main(String[] args) {
		new En();
	}
}
 
X

Xyz1

Gast
Noch eine Idee, man lässt das Shuffle weg und schickt die Positionen durch einen ZipOutputStream, um die Entropie zu erhöhen:
Java:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Semaphore;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class En {
	private final Semaphore SEM = new Semaphore(1);
	private ArrayList<Point> ps = new ArrayList<Point>();
	private String sha256 = "";

	public En() {
		final JPanel p1 = new JPanel();
		final JProgressBar b1 = new JProgressBar();
		final JTextField f2 = new JTextField();
		JButton b2 = new JButton("Stop");
		JPanel p2 = new JPanel(new GridLayout(2, 1));
		JPanel p3 = new JPanel(new BorderLayout());
		p3.add(f2, BorderLayout.CENTER);
		p3.add(b2, BorderLayout.EAST);
		p2.add(b1);
		p2.add(p3);
		JFrame f1 = new JFrame();
		f1.setLayout(new BorderLayout());
		f1.add(p1, BorderLayout.CENTER);
		f1.add(p2, BorderLayout.SOUTH);
		f1.setSize(800, 800);
		f1.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		f1.setVisible(true);

		final Timer timer = new Timer();
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				// we have to use a double try block...
				try {
					SEM.acquire();
					try {
						Point mousePosition = p1.getMousePosition();
						if (mousePosition != null && (ps.isEmpty() || !ps.get(ps.size() - 1).equals(mousePosition))) {
							// new position recognized
							ps.add(mousePosition);
							// capture all positions and send them through a ZipOutputStream
							ByteArrayOutputStream bos = new ByteArrayOutputStream();
							try (ZipOutputStream zos = new ZipOutputStream(bos)) {
								zos.setMethod(ZipOutputStream.DEFLATED);
								zos.setLevel(9);
								zos.putNextEntry(new ZipEntry("a"));
								for (Point point : ps) {
									zos.write(ByteBuffer.allocate(8).putInt(point.x).putInt(point.y).array());
								}
								zos.closeEntry();
							}
							bos.flush();
							// start digesting with Sha256
							MessageDigest md = MessageDigest.getInstance("SHA-256");
							byte[] digest = md.digest(bos.toByteArray());
							StringBuilder b = new StringBuilder(new BigInteger(1, digest).toString(16));
							// extend the resulting String
							while (b.length() < 64) {
								b.insert(0, '0');
							}
							// set the attributes
							sha256 = b.toString();
							int len = ps.size();
							b1.setValue((len < 100 ? len : 100));
							f2.setText(sha256);
							// success
						}
					} finally {
						// if an InterruptedException occurs
						SEM.release();
					}
				} catch (IOException | InterruptedException | NoSuchAlgorithmException e1) {
					e1.printStackTrace();
				}
			}
		}, 0, 100);

		b2.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				timer.cancel();
				try {
					SEM.acquire();
					try {
						System.out.println(ps.size());
						System.out.println(sha256);
					} finally {
						SEM.release();
					}
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
			}
		});
	}

	public static void main(String[] args) {
		new En();
	}
}
 
Ähnliche Java Themen

Ähnliche Java Themen

Neue Themen


Oben