-
Notifications
You must be signed in to change notification settings - Fork 2
/
D01_RsaSignatureString.java
115 lines (111 loc) · 5.54 KB
/
D01_RsaSignatureString.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package net.bplaced.javacrypto.signature;
/*
* Herkunft/Origin: http://javacrypto.bplaced.net/
* Programmierer/Programmer: Michael Fehr
* Copyright/Copyright: frei verwendbares Programm (Public Domain)
* Copyright: This is free and unencumbered software released into the public domain.
* Lizenttext/Licence: <http://unlicense.org>
* getestet mit/tested with: Java Runtime Environment 8 Update 191 x64
* Datum/Date (dd.mm.jjjj): 09.01.2019
* Funktion: signiert und verifiziert einen Text mittels RSA (Asymmetrisch)
* Function: signs and verifies a text string using RSA (asymmetric)
*
* Sicherheitshinweis/Security notice
* Die Programmroutinen dienen nur der Darstellung und haben keinen Anspruch auf eine
* korrekte Funktion, insbesondere mit Blick auf die Sicherheit !
* Prüfen Sie die Sicherheit bevor das Programm in der echten Welt eingesetzt wird.
* The program routines just show the function but please be aware of the security part -
* check yourself before using in the real world !
*/
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.SignatureException;
import javax.xml.bind.DatatypeConverter;
public class D01_RsaSignatureString {
public static void main(String[] args)
throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException, SignatureException {
System.out.println("D01 RSA Signatur mit einem String");
// KeyPair generieren
// Hinweis: RSA-Unterschriften werden ab einer Schlüssellänge von 2.048 Bit als
// sicher angesehen. Hier wird die Länge von 512 Bit nur verwendet, um die
// Ausgabe der erzeugten Schlüssel "klein" zu halten
int rsaKeyLengthInt = 512; // 512, 1024, 2048, 4096, 9192 bit
String rsaHashverfahrenString = "SHA256withRSA"; // SHA256withRSA, SHA384withRSA, SHA512withRSA
KeyPair keyPair = generateRsaKeyPair(rsaKeyLengthInt);
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
// ausgabe der schlüsseldaten
System.out.println("\nprivateKey Länge:" + privateKey.getEncoded().length + " Data:\n"
+ byteArrayPrint(privateKey.getEncoded(), 33));
System.out.println("\npublicKey Länge: " + publicKey.getEncoded().length + " Data:\n"
+ byteArrayPrint(publicKey.getEncoded(), 33));
System.out.println("\nPublic Key : " + publicKey.toString());
// diese nachricht soll signiert werden
String messageString = "Nachricht fuer Signatur";
byte[] messageByte = messageString.getBytes("utf-8");
System.out.println("\nOriginal-Nachricht :" + messageString);
System.out.println("Original-Nachricht hex :" + DatatypeConverter.printHexBinary(messageByte));
// die signatur erfolgt mit dem privaten schlüssel
byte[] signatureByte = signRsa(privateKey, rsaHashverfahrenString, messageByte);
System.out.println(
"\nsignatureByte Länge:" + signatureByte.length + " Data:\n" + byteArrayPrint(signatureByte, 33));
// die überprüfung der signatur erfolgt mit dem öffentlichen schlüssel
System.out.println("\nÜberprüfung der Signatur");
boolean signatureIsCorrectBoolean = verifyRsa(publicKey, rsaHashverfahrenString, messageByte, signatureByte);
System.out.println("Signatur ist korrekt :" + signatureIsCorrectBoolean);
// veränderung der nachricht
System.out.println("\nVeränderung der Nachricht");
messageByte = "Nachricht fuer Signatur2".getBytes("utf-8");
System.out.println("Veränderte-Nachricht hex :" + DatatypeConverter.printHexBinary(messageByte));
signatureIsCorrectBoolean = verifyRsa(publicKey, rsaHashverfahrenString, messageByte, signatureByte);
System.out.println("Signatur ist korrekt :" + signatureIsCorrectBoolean);
}
public static KeyPair generateRsaKeyPair(int keylengthInt) throws NoSuchAlgorithmException {
KeyPairGenerator keypairGenerator = KeyPairGenerator.getInstance("RSA");
keypairGenerator.initialize(keylengthInt, new SecureRandom()); // Achtung: die keylänge von 512 bit ist unsicher
return keypairGenerator.generateKeyPair();
}
public static byte[] signRsa(PrivateKey privateKey, String rsaInstanceString, byte[] messageByte)
throws SignatureException, NoSuchAlgorithmException, InvalidKeyException {
Signature signature = Signature.getInstance(rsaInstanceString);
signature.initSign(privateKey);
signature.update(messageByte);
return signature.sign();
}
public static Boolean verifyRsa(PublicKey publicKey, String rsaInstanceString, byte[] messageByte,
byte[] signatureByte) throws SignatureException, NoSuchAlgorithmException, InvalidKeyException {
Signature publicSignature = Signature.getInstance(rsaInstanceString);
publicSignature.initVerify(publicKey);
publicSignature.update(messageByte);
return publicSignature.verify(signatureByte);
}
public static String byteArrayPrint(byte[] byteData, int numberPerRow) {
String returnString = "";
String rawString = DatatypeConverter.printHexBinary(byteData);
int rawLength = rawString.length();
int i = 0;
int j = 1;
int z = 0;
for (i = 0; i < rawLength; i++) {
z++;
returnString = returnString + rawString.charAt(i);
if (j == 2) {
returnString = returnString + " ";
j = 0;
}
j++;
if (z == (numberPerRow * 2)) {
returnString = returnString + "\n";
z = 0;
}
}
return returnString;
}
}