Beispiel für Java - Digitale Signaturen
InAsymmetric Cryptography example haben wir die Verwendung von Public Key Pair in der Kryptographie diskutiert. Another important use of the Public Key Infrastructure is in Digital Signatures. Digital Signatures are the digital equivalent of handwritten signatures with one important difference; they are not unique but come as a product of the message.
Eine gültige digitale Signatur gibt einem Empfänger Grund zu der Annahme, dass die Nachricht von einem bekannten Absender (authentication) erstellt wurde, dass der Absender nicht leugnen kann, die Nachricht gesendet zu haben (non-repudiation), und dass dies nicht der Fall war während des Transports geändert (integrity). (Quelle:Wikipedia)
1. Generieren Sie ein öffentlich-privates Schlüsselpaar
Der Code zum Generieren eines öffentlich-privaten Schlüsselpaars ist identisch mit dem inAsymmetric
Cryptography example verwendeten Code. Weitere Informationen finden Sie in Schritt 1 oder laden Sie den Quellcode am Ende des Artikels herunter, der alle Quellen enthält -GenerateKeys.java
2. Unterschreiben Sie die Nachricht
Als nächstes müssen wir unsere Nachricht schreiben und sie dann unterschreiben. Die Nachricht und die Signatur können separate Dateien sein. In unserem Beispiel fügen wir sie jedoch zuList
vonbyte[]
hinzu und schreiben sie alsObject
in die Datei.
Message.java
package com.techfou.sender; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.nio.file.Files; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.Signature; import java.security.spec.PKCS8EncodedKeySpec; import java.util.ArrayList; import java.util.List; import javax.swing.JOptionPane; public class Message { private Listlist; //The constructor of Message class builds the list that will be written to the file. //The list consists of the message and the signature. public Message(String data, String keyFile) throws InvalidKeyException, Exception { list = new ArrayList (); list.add(data.getBytes()); list.add(sign(data, keyFile)); } //The method that signs the data using the private key that is stored in keyFile path public byte[] sign(String data, String keyFile) throws InvalidKeyException, Exception{ Signature rsa = Signature.getInstance("SHA1withRSA"); rsa.initSign(getPrivate(keyFile)); rsa.update(data.getBytes()); return rsa.sign(); } //Method to retrieve the Private Key from a file public PrivateKey getPrivate(String filename) throws Exception { byte[] keyBytes = Files.readAllBytes(new File(filename).toPath()); PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory kf = KeyFactory.getInstance("RSA"); return kf.generatePrivate(spec); } //Method to write the List of byte[] to a file private void writeToFile(String filename) throws FileNotFoundException, IOException { File f = new File(filename); f.getParentFile().mkdirs(); ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename)); out.writeObject(list); out.close(); System.out.println("Your file is ready."); } public static void main(String[] args) throws InvalidKeyException, IOException, Exception{ String data = JOptionPane.showInputDialog("Type your message here"); new Message(data, "MyKeys/privateKey").writeToFile("MyData/SignedData.txt"); } }
Ausgabe:
Your file is ready.
3. Überprüfen Sie die Unterschrift
Der Empfänger hat die Datei(he knows it is a List
of 2
byte arrays
; the message and the signature) und möchte überprüfen, ob die Nachricht von der erwarteten Quelle mit einem vorab freigegebenen öffentlichen Schlüssel stammt.
VerifyMessage.java
package com.techfou.receiver; import java.io.File; import java.io.FileInputStream; import java.io.ObjectInputStream; import java.nio.file.Files; import java.security.KeyFactory; import java.security.PublicKey; import java.security.Signature; import java.security.spec.X509EncodedKeySpec; import java.util.List; public class VerifyMessage { private Listlist; @SuppressWarnings("unchecked") //The constructor of VerifyMessage class retrieves the byte arrays from the File //and prints the message only if the signature is verified. public VerifyMessage(String filename, String keyFile) throws Exception { ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename)); this.list = (List ) in.readObject(); in.close(); System.out.println(verifySignature(list.get(0), list.get(1), keyFile) ? "VERIFIED MESSAGE" + "\n----------------\n" + new String(list.get(0)) : "Could not verify the signature."); } //Method for signature verification that initializes with the Public Key, //updates the data to be verified and then verifies them using the signature private boolean verifySignature(byte[] data, byte[] signature, String keyFile) throws Exception { Signature sig = Signature.getInstance("SHA1withRSA"); sig.initVerify(getPublic(keyFile)); sig.update(data); return sig.verify(signature); } //Method to retrieve the Public Key from a file public PublicKey getPublic(String filename) throws Exception { byte[] keyBytes = Files.readAllBytes(new File(filename).toPath()); X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes); KeyFactory kf = KeyFactory.getInstance("RSA"); return kf.generatePublic(spec); } public static void main(String[] args) throws Exception{ new VerifyMessage("MyData/SignedData.txt", "MyKeys/publicKey"); } }
Ausgabe:
VERIFIED MESSAGE ---------------- Hello from example.com!!
Quellcode herunterladen
Herunterladen -digitalsignatures.zip (6 KB)