-
Notifications
You must be signed in to change notification settings - Fork 1
/
E02_EcdhKeyexchange.java
131 lines (116 loc) · 6.6 KB
/
E02_EcdhKeyexchange.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package net.bplaced.javacrypto.keyexchange;
/*
* 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
* getestet mit/tested with: Java Runtime Environment 11.0.1 x64
* Datum/Date (dd.mm.jjjj): 14.01.2019
* Funktion: elektronischer Schlüsselaustausch mittels ECDH
* Function: digital key exchange using ECDH
*
* 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.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.ECGenParameterSpec;
import javax.crypto.KeyAgreement;
public class E02_EcdhKeyexchange {
public static void main(String[] args) throws Exception {
System.out.println("E02 ECDH Schlüsselaustausch");
String ecdhCurvenameString = "secp256r1";
// standard kurvennamen
// secp256r1 [NIST P-256, X9.62 prime256v1]
// secp384r1 [NIST P-384]
// secp521r1 [NIST P-521]
// jeder der beiden benutzer erzeugt ein eigenes schluessel-paar
// variablen fuer den benutzer a
KeyPair aKeyPair = generateEcdhKeyPair(ecdhCurvenameString);
PrivateKey aPrivateKey = aKeyPair.getPrivate(); // der private schluessel von benutzer a
PublicKey aPublicKey = aKeyPair.getPublic(); // der public schluessel von benutzer a
byte[] aSharedSecretByte = null;
// variablen fuer den benutzer b
KeyPair bKeyPair = generateEcdhKeyPair(ecdhCurvenameString);
PrivateKey bPrivateKey = bKeyPair.getPrivate(); // der private schluessel von benutzer b
PublicKey bPublicKey = bKeyPair.getPublic(); // der public schluessel von benutzer b
byte[] bSharedSecretByte = null;
// ausgabe der schluessel fuer jeden benutzer
System.out.println("\n= = = Erzeugung der Schlüssel von Benutzer A = = =");
System.out.println("Benutzer A PrivateKey (Hex):" + printHexBinary(aPrivateKey.getEncoded()));
System.out.println("Benutzer A PublicKey (Hex) :" + printHexBinary(aPublicKey.getEncoded()));
System.out.println("Benutzer A PublicKey :" + aPublicKey.toString());
System.out.println("\n= = = Erzeugung der Schlüssel von Benutzer B = = =");
System.out.println("Benutzer B PrivateKey (Hex):" + printHexBinary(bPrivateKey.getEncoded()));
System.out.println("Benutzer B PublicKey (Hex) :" + printHexBinary(bPublicKey.getEncoded()));
System.out.println("Benutzer B PublicKey :" + bPublicKey.toString());
// nun werden die public keys untereinander getauscht
// in der realen welt wird der public key zB per mail oder einer webseite
// verteilt
// hier werden die beiden public keys "nur" beim jeweils anderen benutzer
// angezeigt
System.out.println("\n= = = Schlüssel bei Benutzer A = = =");
System.out.println("Benutzer A PrivateKey (Hex):" + printHexBinary(aPrivateKey.getEncoded()));
System.out.println("Benutzer B PublicKey (Hex) :" + printHexBinary(bPublicKey.getEncoded()));
System.out.println("\n= = = Schlüssel bei Benutzer B = = =");
System.out.println("Benutzer B PrivateKey (Hex):" + printHexBinary(bPrivateKey.getEncoded()));
System.out.println("Benutzer A PublicKey (Hex) :" + printHexBinary(aPublicKey.getEncoded()));
// erzeugung des shared secret keys bei jedem benutzer
// benutzer a
aSharedSecretByte = createEcdhSharedSecret(aPrivateKey, bPublicKey);
// benutzer b
bSharedSecretByte = createEcdhSharedSecret(bPrivateKey, aPublicKey);
// ausgabe der shared keys fuer jeden benutzer
System.out.println("\n= = = Gemeinsame Schlüssel (SharedSecred) bei den Benutzern = = =");
System.out.println("Benutzer A SharedSecret (Hex):" + printHexBinary(aSharedSecretByte));
System.out.println("Benutzer B SharedSecret (Hex):" + printHexBinary(bSharedSecretByte));
// die laenge des schluessels duerfte zu gross fuer viele aes-verfahren sein,
// daher kuerzen wir den schluessel mittels eines hashes
System.out.println("\nSchlüssel-Länge des SharedSecretByte :" + aSharedSecretByte.length + " Byte/"
+ (aSharedSecretByte.length * 8) + " Bit");
// hashing der ausgabe um einen 32 byte = 256 bit schluessel zu erhalten
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] sharedSecret32Byte = digest.digest(aSharedSecretByte);
System.out.println("= = = Der gemeinsame Schlüssel wird per SHA-256 Hash auf eine Länge von 32 Byte gebracht = = =");
System.out.println("SharedSecretByte nach SHA-256Hash (Hex) :" + printHexBinary(sharedSecret32Byte));
System.out.println("Schlüssel-Länge des SharedSecret32Byte :" + sharedSecret32Byte.length + " Byte/"
+ (sharedSecret32Byte.length * 8) + " Bit");
// ab hier folgt zb die verschluesselung einer datei mittels aes mit nutzung des
// sharedSecret32Byte als key
}
public static KeyPair generateEcdhKeyPair(String curvenameString) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "SunEC");
ECGenParameterSpec ecParameterSpec = new ECGenParameterSpec(curvenameString);
keyPairGenerator.initialize(ecParameterSpec);
return keyPairGenerator.genKeyPair();
}
public static byte[] createEcdhSharedSecret(PrivateKey privateKey, PublicKey publicKey) throws NoSuchAlgorithmException, InvalidKeyException {
KeyAgreement keyAgree = KeyAgreement.getInstance("ECDH");
keyAgree.init(privateKey);
keyAgree.doPhase(publicKey, true);
return keyAgree.generateSecret();
}
public static String printHexBinary(byte[] bytes) {
final char[] hexArray = "0123456789ABCDEF".toCharArray();
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
}