| 
 
 | 
| 
 | Verschlüsselung im HIT-Protokoll für JavaDie Verschlüsselung in der Kommunikation mit HIT läuft über zwei Ebenen: 
 Mehr Details dazu hier. Ein verschlüsselter Datenaustausch erfordert eine erfolgreiche verschlüsselte Anmeldung an HIT. Umgekehrt jedoch erfordert eine erfolgreiche verschlüsselte Anmeldung nicht zwingend einen verschlüsselten Datenaustausch, ist aber zu empfehlen! Es ist (Stand 2023) geplant, den Datenaustausch mittelfristig verpflichtend zu machen, um der IT-Sicherheit zu genügen. Nur mit verschlüsseltem Datenaustausch: Achtung: im Feb. 2024 wurde die Verschlüsselung um weitere Verfahren erweitert und dafür wird eine externe Bibliothek (Bouncy Castle ab v1.76) eingebunden. Damit die bisherige integrierte und die neue Bibliothek unabhängig voneinander arbeiten können, musste die Struktur im Java-Package "de.hi_tier.hitupros" umgestellt werden. Ein bestehendes Javaprogramm kann daher nicht durch bloßes Ersetzen der entsprechenden JAR upgradet werden!musste In den folgenden Beispielen werden Java-Codestücke, HIT-Befehle und -Antworten aus 
optischen Gründen teilweise mehrzeilig angezeigt. Es gibt nun auch eine Demo, die unten beschriebenen Codestücke als Ganzes 
		vereinigt: die Demo verbindet sich mit einem HitServer und führt einen 
		asymmetrisch verschlüsselten LOGON und einen symmetrisch verschlüsselten 
		Datenaustausch (Abfrage und Antworten) durch. Der Javasource 
		ist unter  VerwendungEinfach die Sourcen oder das fertig compilierte JAR des 
		Package  Die zentrale Klasse  ACHTUNG: Bis Feb. 2024 war das die Klasse  HexstringsDa mit Bytes in einem text-basieren Datenaustauschprotokoll nicht 
		gearbeitet werden kann, werden binäre Daten im HIT-Protokoll als 
		Hexstrings aufgefasst. Ein Byte (8 bit) wird in sein entsprechendes 
		hexadezimales Äquivalent in Form einer 2-stelligen Zeichenkette mit dem 
		Zeichensatz  Das Package bietet zwei Hilfsfunktionen, um in beide Richtungen wandeln zu können: von Bytearray zu Hexstring und zurück. Beispiel: das Byte mit dem Wert 72 als Hexstring import de.hi_tier.hitupros.crypto.CryptoHelpers;
byte   demo      = 72;
String hexstring = CryptoHelpers.hexEncode(new byte[] { demo });     // das einzelne Byte in ein Bytearray verpacken
System.out.println(hexstring);Wird der Code ausgeführt, erhält man " Decodieren läuft ähnlich: import de.hi_tier.hitupros.crypto.CryptoHelpers; String hexstring = "49485470"; byte[] demo = CryptoHelpers.hexDecode(hexstring); Öffentlicher SchlüsselDer öffentliche Schlüssel für die asymmetrische Verschlüsselung ist hier veröffentlicht. Dieser kann im Package als Bytearray oder als Hexstring vewendet werden: import de.hi_tier.hitupros.crypto.HitAsymPubKey; String pubkeyHex = "4801525001000...0003010001"; HitAsymPubKey pubkey = new HitAsymPubKey(pubkeyHex); 
 VerbindungsaufbauUnabhängig von unverschlüsseltem oder verschlüsseltem Datenaustausch müssen nach dem Verbindungsaufbau die Antworten als erstes gelesen werden. Nur wenn die Antworten keine Fehler anzeigen (erkennbar an <Schwere> in der Antwortstruktur), darf fortgesetzt werden. Anderenfalls ist zu einer anderen HIT-Serverinstanz zu verbinden. Diese Antworten (nur diese) sind immer unverschlüsselt. Die Antwortzeile mit dem <AntwortCode> (=Plausinummer)  UTF-8Der HIT-Server kann sowohl den Standard-Zeichensatz als 
		auch UTF-8 verstehen. Man sollte daher beim Anlegen eines  Beispiel: import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintStream; import java.nio.charset.StandardCharsets; Charset UTF8_noBOM = StandardCharsets.UTF_8; // = UTF-8 ohne BOM BufferedReader in = new BufferedReader(new InputStreamReader(networkStream,UTF8_noBOM)); PrintStream out = new PrintStream (networkStream,true,UTF8_noBOM); ( Ohne UTF-8 wäre dies lediglich: import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintStream; BufferedReader in = new BufferedReader(new InputStreamReader(networkStream)); PrintStream out = new PrintStream (networkStream,true); Wird UTF-8 verwendet, dann muss beim Anmelden (via Entity  AblaufStatt dass die einzelnen Komponenten für die beiden Verschlüsselungen 
		separat gehandhabt werden, verwaltet die Klasse
		 Pro HITP-Sitzung sollte nur eine HitCrypt-Instanz mitgeführt werden. Asymmetrisch Verschlüsseln für AnmeldungFür die verschlüsselte Anmeldung sind beim Senden der Entität  
 Anlegen eines zufälligen  
import de.hi_tier.hitupros.crypto.HitCrypto;
import de.hi_tier.hitupros.crypto.HitSymKey;
HitCrypto crypt = HitCrypto.getInstance();                  // Instanz für erkannte Crypto-Bibliothek anlegen
crypt.setEncSym("Blowfish/ECB/TBC");                        // Algorithmus, Blockmodus und Padding für symmetrische Verschlüsselung
HitSymKey sessionKey = crypt.generateSymKey();              // anhand ENC_SYM Schlüssel für symmetrische Verschlüsselung generieren
crypt.setSymKey(sessionKey);                                // Session-Key übernehmen in crypt
String sess_key = sessionKey.toHexstring();                 // für LOGON Spalte SESS_KEYMan erhält dann beispielsweise in  DF3D8AAFD57F6601A6700801B725112A869E6542027CAE690E7F5F3B82ED7C5A05D3C1B6B4EF0C4F300DD4E0ACD7D7C8   import de.hi_tier.hitupros.crypto.CryptoHelpers; byte[] randCliBytes = new byte[32]; // erzeuge Array CryptoHelpers.nextRandomBytes(randCliBytes); // fülle zufällige Bytes in Array String rand_cli = CryptoHelpers.hexEncode(randCliBytes); // für LOGON Spalte RAND_CLI BeispielAnmeldung unverschlüsselt: *1:XS:LOGON/BNR15;PIN;MELD_WG;CHA;MAXCERR;TIMEOUT: 09 199 000 0031;Aaaa$900000;3;0;0;1200 erweitert um Spalten für verschlüsselte Anmeldung ohne folgendem verschlüsselten Datenaustausch: *1:XS:LOGON/BNR15;PIN;MELD_WG;CHA;MAXCERR;TIMEOUT;SVR_HELO;RAND_CLI: 09 199 000 0031;Aaaa$900000;3;0;0;1200 ;HitServer bereit. Version 2600, 01.04.2023 00-00. Sie sind mit dem Testsystem T1B_HZ05 verbunden. Nur eingeschraenkt verfuegbar, da hier entwickelt wird. (Server benutzt neue Betriebstabellen/NEWADS) HI-Tierzeit 11.04.2023, 13-19-38h Challenge -2251982346156064082 ;164FD11B482B793CAC1243ED076F731D73A34DB182329EF794C82E8590625B35F16BF3D89A84DA72DC1911ECC53A44B5 erweitert um 
Spalten für verschlüsselte Anmeldung mit folgendem verschlüsselten Datenaustausch 
(Spalte  *1:XS:LOGON/BNR15;PIN;MELD_WG;CHA;MAXCERR;TIMEOUT;SVR_HELO;SESS_KEY;ENC_SYM;RAND_CLI: 09 199 000 0031;Aaaa$900000;3;0;0;1200 ;HitServer bereit. Version 2600, 01.04.2023 00-00. Sie sind mit dem Testsystem T1B_HZ05 verbunden. Nur eingeschraenkt verfuegbar, da hier entwickelt wird. (Server benutzt neue Betriebstabellen/NEWADS) HI-Tierzeit 11.04.2023, 13-19-38h Challenge -2251982346156064082 ;DF3D8AAFD57F6601A6700801B725112A869E6542027CAE690E7F5F3B82ED7C5A05D3C1B6B4EF0C4F300DD4E0ACD7D7C8 ;AES/CBC/TBC ;164FD11B482B793CAC1243ED076F731D73A34DB182329EF794C82E8590625B35F16BF3D89A84DA72DC1911ECC53A44B5 Abschließend wird die ganze Zeile asymmetrisch verschlüsselt und dem erhaltenen Hexstring ein
 import de.hi_tier.hitupros.crypto.HitCrypto; import de.hi_tier.hitupros.crypto.HitAsymPubKey; String pubkeyHex = "4801525001000...0003010001"; // 1:1 wie veröffentlicht HitAsymPubKey pubkey = new HitAsymPubKey(pubkeyHex); // Schlüssel für asymmetrische Verschlüsselung des LOGON HitCrypto crypt = HitCrypto.getInstance(); // Instanz für erkannte Crypto-Bibliothek anlegen crypt.setAsymKey(pubkey); // PublicKey übernehmen String request = "*1:XS:LOGON/BNR15;....11ECC53A44B5"; // kompletter String vom Absatz vorher request = crypt.encodeAsymmetric(request,false,true); // asymmetrisch verschlüsseln und mit $ versehen 
 Das erhaltene  $0202002AC0888754C9E5062134D155...000D2E40BB0C79E8B028647971DA56 (ist inklusive  Die gesamte Zeile kann jetzt (abgeschlossen mit CRLF) als Zeichenkette über die bestehende Socket-Verbindung an HIT gesendet werden. Hat man die Spalte  Übrigens: Client-seitig müssen und können keine asymmetrisch verschlüsselten Zeichenketten decodiert werden, da für den Vorgang der private Schlüssel benötigt wird, den nur die Zentrale Datenbank besitzt. Symmetrisch ver- und entschlüsselnDie Antworten einer erfolgreichen verschlüsselten Anmeldung und folgende 
Anfragen und Antworten sind symmetrisch verschlüsselt, wenn beim  Verschlüsseln, z.B. die Abfrage von bestimmten  import de.hi_tier.hitupros.crypto.HitCrypto; String request = "*2:RS:CODES/CODESET;CODENR;CODE;CODETEXT:CODENR;BW;1;4;ORDER;1;2"; request = crypt.encodeSymmetric(request,false,true); // symmetrisch verschlüsseln mit obigem crypt und mit # versehen Der dafür nötige  Die gesamte Zeile kann jetzt (abgeschlossen mit CRLF) als Zeichenkette über die bestehende Socket-Verbindung an HIT gesendet werden. Entschlüsseln vom HIT-Server erhaltene Antwortzeilen: 
import de.hi_tier.hitupros.crypto.HitCrypto;
// crypt von oben
String response;
while ( (response = readline()) != null) {
   // wenn verschlüsselt, dann erst decodieren
   if (HitCrypto.isSymmetricLine(response)) {
      response = crypt.decodeSymmetric(response.substring(1),false,true)
   }
   // entschlüsselte Antwort auswerten
   HitAntwort antwort = HitAntwort.parse(response);
   // wenn Antwort nicht die letzte, dann lies nächste Zeile von HIT
   if (antwort == null) {
      // es war keine HitAntwort oder entschlüsseln schlug fehl
      throw new IOException();
   }
   else if (antwort.IstLetzteAntwort) {
      // es ist die letzte, also Lesen abbrechen
      break;
   }
   // nächste lesen
}Eine verschlüsselte HIT-Antwort beginnt mit einem  
 Aus einer  #4C2BE5296EC91A8F1B2BADC9FD1462...14E77FE4B0715582DE23D82D6F7AE7 würde dann beispielsweise =2%1652:1/121:CODES:Anzahl Datenzeilen - 1651;Select CODESET,...;Dauer=0.242[Sek.] decodiert. Da die Antwort die letzte in einer Reihe ist (erkennbar am
		 
 Kurz & bündigRelevante Konstruktoren und Methodenaufrufe im Package  Bytes & Strings: 
 
 Schlüssel: 
 Asymmetrisch verschlüsseln: 
 Symmetrisch ver- und entschlüsseln 
 | 
|   |