[JAVA] Lassen Sie uns die Verschlüsselungsverarbeitung durchführen!

Dieser Artikel ist der Artikel zum 18. Tag des Java-Adventskalenders 2016. Am Tag zuvor war es fullmetal248s "Eine Geschichte über das Bemühen, JAR-Dateien zu dekompilieren". Morgen ist yumix_hs "Geburtstagsrahmen!"

Kryptografische Verarbeitung

Was ist Verschlüsselung?

Bei der Verschlüsselung werden die Originaldaten (z. B. eine Zeichenfolge) in etwas konvertiert, das Sie auf den ersten Blick nicht verstehen. Mit dem Entschlüsselungsschlüssel können Sie die ursprüngliche Zeichenfolge wiederherstellen, die als Entschlüsselung bezeichnet wird. Die Java-Sprache verfügt über eine kryptografische Verarbeitungsbibliothek im Paket javax.crypto, sodass eine kryptografische Verarbeitung mit verschiedenen Verschlüsselungsmethoden durchgeführt werden kann.

Kryptografische Verarbeitung

Im Folgenden werden die AES-Chiffren erläutert, die häufig bei der kryptografischen Verarbeitung verwendet werden. Da ich eine Bibliotheksklasse für die Verwendung der AES-Verschlüsselung in einem Programm erstellt habe, werde ich auch den Quellcode und dessen Verwendung erläutern.

Beginnen wir mit Grundkenntnissen der AES-Verschlüsselung.

Was ist AES-Verschlüsselung?

In der zweiten Hälfte der neunziger Jahre wurde klar, dass der von der US-Regierung für den öffentlichen Gebrauch verwendete DES-Code von einigen PCs (möglicherweise mit etwa 30) beschädigt werden würde. Aus diesem Grund haben wir uns entschlossen, einen Weltwettbewerb abzuhalten und neue Verschlüsselungsmethoden zu fordern. Es gab Einträge wie elliptischen Code aus Japan, aber der AES-Code wurde schließlich übernommen.

CBC-Modus

Die AES-Verschlüsselung schneidet das Ganze in kleine Blöcke und führt die Verschlüsselungsverarbeitung nach und nach durch. Zu diesem Zeitpunkt besteht der CBC-Modus darin, das XOR des unmittelbar zuvor verschlüsselten Blocks und den Block, der als nächstes verschlüsselt werden soll, zu nehmen und dann zu verschlüsseln. Da die Verschlüsselung des vorherigen Blocks die Verschlüsselung des nächsten Blocks beeinflusst, hat sie die hervorragende Eigenschaft, dass nicht erraten werden kann, welche Art von Verschlüsselung eine bestimmte Zeichenfolge durch Vergleichen des Klartextes und der Verschlüsselung codiert. Es gibt.

IV(Initial Vector)

Im CBC-Modus hat der erste Block keine XOR-überlappenden Datenblöcke. Daher wird für den ersten Block ein Wert künstlich erzeugt, dies ist jedoch IV. IV ist eine 128-Bit-Zeichenfolge, wenn Standard-Java-Klassen verwendet werden.

Erstellen Sie IV mit einer zufälligen Zeichenfolge

Wenn Sie während des Verschlüsselungsprozesses jedes Mal eine andere IV angeben, können Sie jedes Mal denselben Klartext, aber unterschiedliche Verschlüsselung verwenden. IV verwendet also eine zufällige Zeichenfolge. Verwenden Sie RandomStringUtils in Commons Library (commons-lang3-3.4-bin.zip), um zufällige Zeichenfolgen abzurufen , Sie können einfach generieren, indem Sie die Länge und den Typ der zu verwendenden Zeichen angeben.

Entschlüsselungsschlüssel

Eine Schlüsselzeichenfolge, die sowohl für die Verschlüsselung als auch für die Entschlüsselung verwendet wird. Dies sollte auch 128 Bit oder genau 16 Zeichen sein. Sie können den Inhalt frei erstellen. Wenn der Entschlüsselungsschlüssel jedoch zu lang ist, wird er abgeschnitten, und wenn er zu kurz ist, wird die Zeichenfolge ergänzt.

Quellcode für die Crypto-Klasse, die die kryptografische Verarbeitung durchführt

Das Folgende ist eine Bibliotheksklasse, die verschlüsselt und entschlüsselt. Um die Verschlüsselung durchzuführen, erstellen Sie einfach eine Instanz der Crypt-Klasse und verwenden Sie die Verschlüsselungs- oder Entschlüsselungsmethode. Da es jedoch erforderlich ist, den Schlüssel und IV bei der Verwendung zu speichern, wird später ein Beispiel für eine bestimmte Verwendung veröffentlicht.

Zuerst brauchen wir eine Commons-Klasse, also hier ist die pom.xml-Datei dafür. Ich habe die Bedeutung und Verwendung von pom in Gepostet am 13. geschrieben. Schauen Sie also bitte dort nach.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>crypto</groupId>
	<artifactId>crypto</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<dependencies>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.5</version>
		</dependency>
	</dependencies>
	<build>
		<sourceDirectory>src</sourceDirectory>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.5.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Als nächstes folgt die Crypto-Klasse für die kryptografische Verarbeitung. Das Projekt wird in Eclipse erstellt, nachdem ein normales Java-Projekt erstellt wurde. Klicken Sie mit der rechten Maustaste auf das Projekt und wählen Sie [Konfiguration] ⇒ [In Maven-Projekt konvertieren].

package com.tkxwebs.crypto;
import java.io.Serializable;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
 *AES-Verschlüsselung/Kryptografische Klasse im CBC-Modus
 * @Autor Takashi Kawaba [email protected] 
 */
public class Crypto implements Serializable {
    private Cipher encrypter; //Kryptowährung für die Verschlüsselung
    private Cipher decrypter; //Verschlüsselungsgerät zur Entschlüsselung
 
    /*Konstruktor (Argumente sind Entschlüsselungsschlüssel und IV)
     *Beide Argumente reichen von String bis Byte[]Geben Sie an, in was konvertiert wurde
     */
    public Crypto(byte[] secretKey, byte[] ivs) throws Exception{
        IvParameterSpec iv = new IvParameterSpec(ivs);    //Erstellen Sie zum Zeitpunkt der Verschlüsselung den Anfangswert für den Startblock
         
        SecretKeySpec key = new SecretKeySpec(secretKey, "AES"); //Erstellen Sie eine Reihe von Verschlüsselungsmethoden + Entschlüsselungsschlüssel
        encrypter = Cipher.getInstance("AES/CBC/PKCS5Padding");  //Erstellen Sie ein Verschlüsselungsgerät, indem Sie die Verschlüsselungsmethode und die Generierungsmethode angeben
        encrypter.init(Cipher.ENCRYPT_MODE, key, iv);            //Stellen Sie das Verschlüsselungsgerät auf den Verschlüsselungsmodus ein
 
        decrypter = Cipher.getInstance("AES/CBC/PKCS5Padding");  //Erstellen Sie ein anderes Verschlüsselungsgerät
        decrypter.init(Cipher.DECRYPT_MODE, key, iv);            //Stellen Sie das Verschlüsselungsgerät in den Entschlüsselungsmodus
    }
 
    /*Methode zur Durchführung des Verschlüsselungsprozesses*/
    public String encrypto(String text) throws Exception {
        byte[] crypto = encrypter.doFinal(text.getBytes()); //Verschlüsseln
        byte[] str64 = Base64.getEncoder().encode(crypto);  //In ein Array von Zeichen zur Anzeige konvertieren
        return new String(str64);                           //Machen Sie es zu einer Zeichenkette
    }
    /*Methode zur Durchführung des Entschlüsselungsprozesses*/
    public String decrypto(String str64) throws Exception {
        byte[] str = Base64.getDecoder().decode(str64);     //Konvertieren Sie die Verschlüsselungszeichenfolge zurück in die ursprüngliche Binärdatei
        byte[] text = decrypter.doFinal(str);               //Entschlüsseln
        return new String(text);                            //In String konvertieren und zurückgeben
    }
}

Die folgende FileUtil-Klasse ist ein Dienstprogramm zum Speichern des Verschlüsselungsschlüssels und von IV.

package com.tkxwebs.crypto;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class FileUtil {
	public static void writeBytes(byte[] b, String path) {
		try(ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream(path))) {
			o.write(b);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static byte[] readBytes(String path) {
		byte[] b = new byte[16];
		try(ObjectInputStream in = new ObjectInputStream(new FileInputStream(path))) {
			in.read(b, 0, 16);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return b;
	}
}

Verwendung der Crypto-Klasse

Mal sehen, wie man es tatsächlich benutzt.

Wann verwenden Sie Kryptografie? Es verschlüsselt Passwörter usw. Dann wird es entschlüsselt, wenn es beispielsweise beim Anmeldevorgang sortiert wird. Offensichtlich werden Verschlüsselung und Entschlüsselung zu unterschiedlichen Zeiten ausgeführt.

Daher müssen der Entschlüsselungsschlüssel und IV zur Speicherung in einer Datei oder Datenbank im System aufgezeichnet (und weiter verschlüsselt) werden. Hier wird der weitere Verschlüsselungsprozess weggelassen, aber in jedem Fall müssen der Entschlüsselungsschlüssel und der Entschlüsselungsschlüssel zum Zeitpunkt der Verschlüsselung und Entschlüsselung ausgeschrieben oder ausgelesen werden.

In diesem Anwendungsbeispiel wird ein Dienstprogramm (FileUtil-Klasse) zum Lesen und Schreiben verwendet, das das Byte-Array als Objekt in einer Datei speichert.

Anwendungsfallcode

package sample;
import org.apache.commons.lang3.RandomStringUtils;
import com.tkxwebs.crypto.Crypto;
import com.tkxwebs.crypto.FileUtil;
 
public class CryptoExample {
    public static void main(String args[]) {
        /*******************************************************************************
         *Da Verschlüsselung und Entschlüsselung normalerweise getrennt erfolgen, sind der Entschlüsselungsschlüssel und IV Dateien.
         *Speichern und laden zur Laufzeit zur Verwendung
         *******************************************************************************/
 
        /*------------------------------------------------------------------------------
Datenaufbereitung
        --------------------------------------------------------------------------------*/
        byte[] iv  = RandomStringUtils.randomAlphanumeric(16).getBytes();// IV(Anfangswert 128 Bit feste Länge für den Startblock zum Zeitpunkt der Verschlüsselung)
        byte[] key = "kawaba_2015_key_".getBytes();  //Entschlüsselungsschlüssel(128-Bit-Festlänge)
         
        /*------------------------------------------------------------------------------
Speichern Sie IV und Entschlüsselungsschlüssel in der Datei
        --------------------------------------------------------------------------------*/
        FileUtil.writeBytes(iv,  "iv");       
        FileUtil.writeBytes(key, "secret");
 
        /*------------------------------------------------------------------------------
Anzeige von Daten
        --------------------------------------------------------------------------------*/
        System.out.println("IV(Anfangswert für Startblock)="+new String(iv)+ "("+iv.length + "byte)");
        System.out.println("Entschlüsselungsschlüssel =" + new String(key) + "(16byte)");        
         
        /*------------------------------------------------------------------------------
Verschlüsselungsverarbeitung
        --------------------------------------------------------------------------------*/
        String source = "Was soll ich machen"; //Zu verschlüsselnde Zeichenfolge
        String result = "";                //Verschlüsselte Ergebniszeichenfolge
        try {                                                                              //Erstellen Sie ein Crypto-Objekt
            Crypto c = new Crypto(FileUtil.readBytes("secret"), FileUtil.readBytes("iv")); //Entschlüsselungsschlüssel und IV aus der Datei lesen
            result = c.encrypto(source);                                                    //Holen Sie sich die verschlüsselte Zeichenfolge
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("Code =" + result);  //Zeigen Sie die verschlüsselte Zeichenfolge an
         
        /*------------------------------------------------------------------------------
Entschlüsselungsprozess
        --------------------------------------------------------------------------------*/
        try {                                                                              //Erstellen Sie ein Crypto-Objekt
            Crypto c2 =new Crypto(FileUtil.readBytes("secret"), FileUtil.readBytes("iv")); //Entschlüsselungsschlüssel und IV aus der Datei lesen
            result = c2.decrypto(result);                                                   //Holen Sie sich die entschlüsselte Zeichenfolge
        } catch (Exception e) {
            e.printStackTrace();
        }        
        System.out.println("Entschlüsselung =" + result);  //Zeigen Sie die ursprüngliche Zeichenfolge an
    }
}

Wenn ich diesen Code ausführe, erhalte ich Folgendes: Versuchen Sie es einige Male und stellen Sie sicher, dass dieselbe Zeichenfolge jedes Mal in eine andere Verschlüsselung konvertiert wird.

IV(Anfangswert für Startblock)=u7aTAfOMMKJvD02S(16byte)
Entschlüsselungsschlüssel = kawaba_2015_key_(16byte)
Code = piiKP/GX3HcykHbXAHjptPDtEORdx6oASa2luFtAbZA=
Entschlüsselung = Was wäre wenn

Recommended Posts

Lassen Sie uns die Verschlüsselungsverarbeitung durchführen!
Bildverarbeitung: Spielen wir mit dem Bild
Machen wir eine Weihnachtskarte mit Verarbeitung!