Dieses ist ein Beispiel für das dritte asymmetrische Verschlüsselungsverfahren namens ECIES. Die beiden führenden Buchstaben „EC“ stehen für „Elliptic Curve“ oder „Elliptische Kurven“, welche als Grundlage für dieses Verfahren dienen. Bei der Verschlüsselung mittels „EC“ gibt es keine direkte Schlüssellänge als Indiz für die Stärke der Verschlüsselung, sondern Ihr könnt nur über den verwendeten Kurvennamen einen Hinweis auf die Schlüssellängen erhalten.
An dieser Stelle gibt es von mir keinen Hinweis wie „längere Schlüssel = höhere Sicherheit“, denn bei Elliptischen Kurven entstehen schnell Glaubensfragen, da eine Elliptische Kurve und damit deren „Aussehen“ über Parameter definiert wird. Die richtige Auswahl der Parameter entscheidet am Ende über eine höhere oder geringere Sicherheit. Es gibt immer wieder Gerüchte, dass die amerikanische „National Security Agency“ (oder kurz „NSA“) bei der Parameterauswahl von einigen Kurven „mitgeredet“ haben soll und sich so einen Vorteil (oder gar eine Hintertür) verschafft hat, um einen derart verschlüsselten Datensatz entschlüsseln zu können. Wie gesagt – das könnt Ihr glauben oder auch nicht, faktisch ist die Elliptische Kurven Kryptographie nach heutigem Stand sicherer als die RSA- und DSA-Varianten.
In den Zeilen 56-60 sind einige Kurvennamen aufgeführt, die Ihr durch Auskommentieren nutzen könnt. Eine Übersicht über die in Bouncy Castle implementierten Kurven ist im Bouncy Castle Wiki zu finden.
Hier nun der Steckbrief:
Verschlüsselungssteckbrief | |
Name des Verfahrens | ECIES |
Langname | Elliptic Curves Integrated Encryption Scheme |
Art der Chiffre | Kompletter Plaintext |
Blocklänge (Byte) | – |
Schlüssellänge (Byte/Bit) | Nutzung von Kurvennamen |
Padding genutzt | Nein |
Sicherheit | grundsätzlich sicher |
Besonderes | Geeignet nur für kleine Datenmengen |
Bitte die nachfolgende Routine nicht für den Echteinsatz nutzen, da sie aus kryptographischer Sicht sehr angreifbar ist !
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 |
package net.bplaced.javacrypto.asymmetricencryption; /* * 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): 26.12.2018 * Funktion: verschlüsselt einen Text mittels ECIES (Asymmetrisch) * Function: encrypts a text string using ECIES (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.security.InvalidKeyException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; import java.security.spec.ECGenParameterSpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.xml.bind.DatatypeConverter; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class C05_Ecies { public static void main(String[] args) throws Exception { System.out.println("C05 ECIES Verschlüsselung"); // benötigt Bouncy Castle Security.addProvider(new BouncyCastleProvider()); String plaintextString = "Das ist die geheime Nachricht"; //String plaintextString ="1234567890123456789012345678901234567890123456789012345678901234567890"; byte[] plaintextByte = plaintextString.getBytes("utf-8"); byte[] ciphertextByte = null; byte[] decryptedtextByte = null; // erzeugung eines schlüsselpaares KeyPairGenerator ecGenerator = KeyPairGenerator.getInstance("ECIES", "BC"); // name der verwendeten kurve String curveNameString = "secp256r1"; //String curveNameString = "secp256k1"; //String curveNameString = "brainpoolP256R1"; //String curveNameString = "secp384r1"; //String curveNameString = "secp521r1"; ecGenerator.initialize(new ECGenParameterSpec(curveNameString)); // der name der verwendeten kurve KeyPair ecKeyPair = ecGenerator.generateKeyPair(); ECPublicKey ecPublicKey = (ECPublicKey) ecKeyPair.getPublic(); ECPrivateKey ecPrivateKey = (ECPrivateKey) ecKeyPair.getPrivate(); // verschlüsselung mit dem öffentlichen schlüssel ciphertextByte = EcEncrypt(plaintextByte, ecPublicKey); // entschlüsselung mit dem privaten schlüssel decryptedtextByte = EcDecrypt(ciphertextByte, ecPrivateKey); System.out.println(); System.out.println("ECIES Schlüsselerzeugung"); System.out.println("verwendete Elliptic Curve:" + curveNameString); System.out.println("ecPrivateKey (Byte) Länge:" + ecPrivateKey.getEncoded().length + " Bytes"); System.out.println(byteArrayPrint(ecPrivateKey.getEncoded(), 33)); System.out.println("ecPublicKey (Byte) Länge:" + ecPublicKey.getEncoded().length + " Bytes"); System.out.println(byteArrayPrint(ecPublicKey.getEncoded(), 33)); System.out.println(); System.out.println("ECIES Verschlüsselung"); System.out.println("plaintextString :" + plaintextString); System.out.println("plaintextByte Länge:" + plaintextByte.length + " Bytes Data:" + DatatypeConverter.printHexBinary(plaintextByte)); System.out.println("ciphertextByte Länge:" + ciphertextByte.length + " Bytes"); System.out.println(byteArrayPrint(ciphertextByte,33)); System.out.println("decryptedtextByte :" + DatatypeConverter.printHexBinary(decryptedtextByte)); System.out.println("decryptedtextString:" + new String(decryptedtextByte)); System.out.println(); } public static byte[] EcEncrypt(byte[] plaintextByte, ECPublicKey publicKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException { byte[] ciphertextByte = null; Cipher encryptCipher = Cipher.getInstance("ECIES", "BC"); encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey); ciphertextByte = encryptCipher.doFinal(plaintextByte); return ciphertextByte; } public static byte[] EcDecrypt(byte[] ciphertextByte, ECPrivateKey privateKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException { byte[] decryptedtextByte = null; Cipher decryptCipher = Cipher.getInstance("ECIES", "BC"); decryptCipher.init(Cipher.DECRYPT_MODE, privateKey); decryptedtextByte = decryptCipher.doFinal(ciphertextByte); return decryptedtextByte; } 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; } } |
Auf der Konsole ist folgende Ausgabe zu sehen:
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 |
C05 ECIES Verschlüsselung ECIES Schlüsselerzeugung verwendete Elliptic Curve:secp256r1 ecPrivateKey (Byte) Länge:150 Bytes 30 81 93 02 01 00 30 13 06 07 2A 86 48 CE 3D 02 01 06 08 2A 86 48 CE 3D 03 01 07 04 79 30 77 02 01 01 04 20 49 7E 53 96 D8 85 AB 0F 59 B7 50 09 57 E4 25 ED F6 13 BF 94 FA 14 1B F8 48 18 BF 04 5F A5 50 E9 A0 0A 06 08 2A 86 48 CE 3D 03 01 07 A1 44 03 42 00 04 42 88 B9 29 C7 BA 59 97 F3 AA CD 5B 69 AA A6 B0 CE 6E D1 8F 6C 3B DF 61 DA 3B 73 79 68 73 D9 83 22 72 1C 81 61 47 7C FE 45 3B 92 21 9A 2C 94 F3 D0 2D 02 FB 83 2B 9B 0A 96 6C F5 88 10 E0 39 0D ecPublicKey (Byte) Länge:91 Bytes 30 59 30 13 06 07 2A 86 48 CE 3D 02 01 06 08 2A 86 48 CE 3D 03 01 07 03 42 00 04 42 88 B9 29 C7 BA 59 97 F3 AA CD 5B 69 AA A6 B0 CE 6E D1 8F 6C 3B DF 61 DA 3B 73 79 68 73 D9 83 22 72 1C 81 61 47 7C FE 45 3B 92 21 9A 2C 94 F3 D0 2D 02 FB 83 2B 9B 0A 96 6C F5 88 10 E0 39 0D ECIES Verschlüsselung plaintextString :Das ist die geheime Nachricht plaintextByte Länge:29 Bytes Data:44617320697374206469652067656865696D65204E6163687269636874 ciphertextByte Länge:114 Bytes 04 B6 7A 27 79 AD D3 FF 7C C8 6B 79 92 1B 56 30 8A B9 34 E2 42 AA 09 61 1C 42 BC 89 E4 C5 8C 4F BA 5B 8A 9E 6F 61 51 ED F9 F4 59 30 2F 71 ED B2 DB 8B DE 6D AF 5A C0 BC A2 56 50 82 3E 0C A5 0B 31 76 5C 07 48 88 22 82 4C E0 FC 4D 34 76 45 EB 7F 13 4C DD 7F 09 58 0F 76 53 A6 07 A8 5C 50 12 B9 62 B0 3E 27 6E 2C 85 F2 EA 6B A1 C5 83 38 C0 B3 9A decryptedtextByte :44617320697374206469652067656865696D65204E6163687269636874 decryptedtextString:Das ist die geheime Nachricht |
Die Lizenz zum obigen Beispiel findet Ihr auf der eigenen Lizenz-Seite.
Letzte Aktualisierung: 26.12.2018