[Java] Verwenden Sie kryptografische Technologie mit Standardbibliotheken

Liste der in diesem Artikel vorgestellten kryptografischen Technologien

Wir haben zusammengefasst, wie die folgenden kryptografischen Techniken mit der Standardbibliothek von Java behandelt werden. Wir werden jede kryptografische Technologie kurz erläutern und ein Implementierungsbeispiel vorstellen.

Die in den Implementierungsbeispielen verwendeten Algorithmen sind in Klammern aufgeführt.

Symmetrischer Code

Was ist symmetrischer Code?

Symmetrische Verschlüsselung ist eine Technologie zum Schutz der Vertraulichkeit von Nachrichten. Es hat die folgenden Funktionen.

Verwendung der symmetrischen Verschlüsselung

Schlüsselgenerierung

Dies ist eine Methode zum Generieren eines symmetrischen Verschlüsselungsschlüssels (allgemeiner Schlüssel).

    public SecretKey generateKey() throws NoSuchAlgorithmException {

        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(128);

        return keyGen.generateKey();
    }

Erzeugung eines Initialisierungsvektors

So generieren Sie einen Initialisierungsvektor. Der Initialisierungsvektor ist eine zufällige Bitfolge, die verwendet werden soll, damit jedes Mal unterschiedliche Chiffren erhalten werden können, selbst wenn sie mit demselben Schlüssel verschlüsselt werden.

    public IvParameterSpec generateIV() {

        SecureRandom random = new SecureRandom();
        byte[] iv = new byte[16];
        random.nextBytes(iv);

        return new IvParameterSpec(iv);
    }

Nachrichtenverschlüsselung

So verschlüsseln Sie die Nachricht. Geben Sie den Algorithmus, den Blockmodus und die Auffüllmethode an, wenn Sie die Cipher-Instanz abrufen. In JavaDoc für die Klasse "Cipher" finden Sie eine Kombination aus Algorithmen, Blockmodi und Füllmethoden.

    public byte[] encrypto(String plainText, SecretKey key, IvParameterSpec iv) throws GeneralSecurityException {

        //Format:"Algorithmus/Blockmodus/Auffüllmethode"
        Cipher encrypter = Cipher.getInstance("AES/CBC/PKCS5Padding");
        encrypter.init(Cipher.ENCRYPT_MODE, key, iv);

        return encrypter.doFinal(plainText.getBytes());
    }

Entschlüsselung des Codes

Dies ist die Methode zum Entschlüsseln des Codes. Geben Sie den Algorithmus, den Blockmodus und die Auffüllmethode wie für die Verschlüsselung an.

    public String decrypto(byte[] cryptoText, SecretKey key, IvParameterSpec iv) throws GeneralSecurityException {

        //Format:"Algorithmus/Blockmodus/Auffüllmethode"
        Cipher decrypter = Cipher.getInstance("AES/CBC/PKCS5Padding");
        decrypter.init(Cipher.DECRYPT_MODE, key, iv);

        return new String(decrypter.doFinal(cryptoText));
    }

Verschlüsselung mit öffentlichem Schlüssel

Was ist Verschlüsselung mit öffentlichem Schlüssel?

Die Verschlüsselung mit öffentlichen Schlüsseln ist eine Technologie zum Schutz der Vertraulichkeit von Nachrichten. Es hat die folgenden Funktionen.

Verwendung der Verschlüsselung mit öffentlichem Schlüssel

Schlüsselgenerierung

Dies ist eine Methode zum Generieren eines Verschlüsselungsschlüsselpaars mit öffentlichem Schlüssel (öffentliches Schlüssel / privates Schlüsselpaar).

    public KeyPair generateKeyPair() throws NoSuchAlgorithmException {

        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2024);

        return keyGen.generateKeyPair();
    }

Beziehen Sie den öffentlichen / privaten Schlüssel vom Schlüsselpaar.

    KeyPair keyPair = generateKeyPair();
    PublicKey publickey = keyPair.getPublic();
    PrivateKey privatekey = keyPair.getPrivate();

Nachrichtenverschlüsselung

So verschlüsseln Sie die Nachricht. Mit dem ** öffentlichen Schlüssel ** verschlüsseln. Geben Sie den Algorithmus, den Blockmodus und die Auffüllmethode an, wenn Sie die Cipher-Instanz abrufen. In JavaDoc für die Klasse "Cipher" finden Sie eine Kombination aus Algorithmen, Blockmodi und Füllmethoden.

    public byte[] encrypto(String plainText, PublicKey publickey) throws GeneralSecurityException {

        //Format:"Algorithmus/Blockmodus/Auffüllmethode"
        Cipher encrypter = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        encrypter.init(Cipher.ENCRYPT_MODE, publickey);

        return encrypter.doFinal(plainText.getBytes());
    }

Entschlüsselung des Codes

Dies ist die Methode zum Entschlüsseln des Codes. Entschlüsseln Sie mit dem ** privaten Schlüssel **. Geben Sie den Algorithmus, den Blockmodus und die Auffüllmethode wie für die Verschlüsselung an.

    public String decrypto(byte[] cryptoText, PrivateKey privatekey) throws GeneralSecurityException {

        Cipher decrypter = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        decrypter.init(Cipher.DECRYPT_MODE, privatekey);

        return new String(decrypter.doFinal(cryptoText));
    }

Einweg-Hash-Funktion

Was ist eine Einweg-Hash-Funktion?

Die Einweg-Hash-Funktion ist eine Technik zum Erkennen von Nachrichtenmanipulationen. Es hat die folgenden Funktionen.

Verwendung der Einweg-Hash-Funktion

Nachrichten-Hashing

Wie man eine Nachricht hasht. In Java werden Einweg-Hash-Funktionen als "Message Digests" bezeichnet.

    private byte[] hash(String plainText) throws NoSuchAlgorithmException {

        MessageDigest md = MessageDigest.getInstance("SHA-256");

        return md.digest(plainText.getBytes());
    }

Manipulationserkennung

Dies ist eine Methode zum Erkennen von Manipulationen. Alles was Sie tun müssen, ist den Hash-Wert erneut zu erhalten und zu vergleichen.

    private boolean verify(String plainText, byte[] givenHash) throws NoSuchAlgorithmException {

        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] newHash = md.digest(plainText.getBytes());

        return Arrays.equals(givenHash, newHash);
    }

Nachrichtenüberprüfungscode

Was ist ein Nachrichtenüberprüfungscode?

Der Nachrichtenauthentifizierungscode (MAC) ist eine Technologie zum Erkennen von Nachrichtenmanipulationen und "Spoofing". Es hat die folgenden Funktionen.

Verwendung des Nachrichtenüberprüfungscodes

Schlüsselgenerierung

Dies ist die Methode zum Generieren des Nachrichtenauthentifizierungscode-Schlüssels (allgemeiner Schlüssel).

    public SecretKey generateKey() throws NoSuchAlgorithmException {

        KeyGenerator keyGen = KeyGenerator.getInstance("HmacSHA256");

        return keyGen.generateKey();
    }

MAC-Wert abrufen

So erhalten Sie den MAC-Wert einer Nachricht.

    private byte[] mac(String plainText, SecretKey key) throws GeneralSecurityException {

        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(key);

        return mac.doFinal(plainText.getBytes());
    }

Manipulationserkennung

Dies ist eine Methode zum Erkennen von Manipulationen. Sie müssen lediglich den MAC-Wert erneut abrufen und vergleichen.

    private boolean verify(String plainText, SecretKey key, byte[] givenMac) throws GeneralSecurityException {

        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(key);
        byte[] newMac = mac.doFinal(plainText.getBytes());

        return Arrays.equals(givenMac, newMac);
    }

Digitale Unterschrift

Was ist eine digitale Signatur?

Die digitale Signatur ist eine Technologie zum Erkennen von Nachrichtenmanipulationen und "Spoofing". Es hat die folgenden Funktionen.

--Verwenden Sie unterschiedliche Schlüssel für Absender und Empfänger der Nachricht

Verwendung der digitalen Signatur

Schlüsselgenerierung

So generieren Sie ein digitales Signaturschlüsselpaar (öffentlicher Schlüssel / privates Schlüsselpaar).

    public KeyPair generateKey() throws NoSuchAlgorithmException {

        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2024);

        return keyGen.generateKeyPair();
    }

Beziehen Sie den öffentlichen / privaten Schlüssel vom Schlüsselpaar.

    KeyPair keyPair = generateKey();
    PublicKey publickey = keyPair.getPublic();
    PrivateKey privatekey = keyPair.getPrivate();

Unterschreiben Sie die Nachricht

So unterschreiben Sie eine Nachricht. Unterschreiben Sie mit dem ** privaten Schlüssel **.

    public byte[] sign(String plainText, PrivateKey privatekey) throws GeneralSecurityException {

        Signature sign = Signature.getInstance("SHA256withRSA");
        sign.initSign(privatekey);
        sign.update(plainText.getBytes());

        return sign.sign();
    }

Signaturprüfung

So überprüfen Sie die Signatur. Validieren Sie mit dem ** öffentlichen Schlüssel **.

    public boolean verify(String plainText, byte[] sign, PublicKey publicKey) throws GeneralSecurityException {

        Signature verify = Signature.getInstance("SHA256withRSA");
        verify.initVerify(publicKey);
        verify.update(plainText.getBytes());

        return verify.verify(sign);
    }

Diffie-Hellman-Schlüsselaustausch

Was ist Diffie-Hellman-Schlüsselaustausch?

Der Diffie-Hellman-Schlüsselaustausch ist eine Technologie zum sicheren Teilen eines gemeinsamen Schlüssels zwischen dem Absender und dem Empfänger einer Nachricht. Es hat die folgenden Funktionen.

Diffie-Hellman-Schlüsselaustauschverfahren

Das Verfahren für den Diffie-Hellman-Schlüsselaustausch ist kompliziert. Lassen Sie uns das Verfahren organisieren, bevor wir die Verwendung im Detail erläutern. Bitten Sie Alice (Absender) und Bob (Empfänger), das Verfahren zu erläutern.

Wenn Alice und Bob Schlüssel austauschen, führen Sie die folgenden Schritte aus, um einen gemeinsamen Schlüssel zu generieren.

    1. Alice erzeugt eine große Primzahl P und eine Quelle G.
  1. Sende P und G von Alice an Bob
    1. Alice bekommt den geheimen Wert X und den öffentlichen Wert Y. Vier. Bob erhält den geheimen Wert X und den öffentlichen Wert Y. Fünf. Alice und Bob tauschen öffentlichen Wert Y aus
  2. Alice generiert einen gemeinsamen Schlüssel
  3. Bob generiert einen gemeinsamen Schlüssel

Verwendung des Diffie-Hellman-Schlüsselaustauschs

Befolgen Sie die oben beschriebenen Schritte, um den Schlüsselaustausch zu erläutern.

1. Alice erzeugt eine große Primzahl P und eine Quelle G.

Generieren Sie zuerst ein Schlüsselpaar und erhalten Sie P und G aus dem Schlüsselpaar.

    //Schlüsselpaargenerierung
    public KeyPair generateKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DiffieHellman");
        keyGen.initialize(2048);
        return keyGen.generateKeyPair();
    }
    //Holen Sie sich P und G.
    KeyPair keyPair = generateKeyPair();

    DHPublicKey publicKey = (DHPublicKey) keyPair.getPublic();
    DHParameterSpec paramSpec = publicKey.getParams();
    BigInteger p = paramSpec.getP();
    BigInteger g = paramSpec.getG();

In Java sind die Werte von P und G fest. Informationen zu P- und G-Werten finden Sie in der Dokumentation zum Standardalgorithmus der Java-Verschlüsselungsarchitektur.

https://docs.oracle.com/javase/jp/8/docs/technotes/guides/security/StandardNames.html#algspec Algorithmusspezifikationen → Algorithmus zur Generierung von DSA-Schlüsselpaaren → Standardwerte von Parametern

2. Senden Sie P und G von Alice an Bob

Sende P und G von Alice an Bob. Zu diesem Zeitpunkt können die Werte von P und G von einem Dritten gesehen werden. Bob generiert ein Schlüsselpaar basierend auf dem empfangenen P und G.

    public KeyPair generateKeyPair(BigInteger p, BigInteger g) throws GeneralSecurityException {

        DHParameterSpec paramSpec = new DHParameterSpec(p, g);
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DiffieHellman");
        keyGen.initialize(paramSpec);

        return keyGen.generateKeyPair();
    }

3. Alice erhält den geheimen Wert X und den öffentlichen Wert Y.

Alice erhält den geheimen Wert X und den öffentlichen Wert Y.

    //Holen Sie sich den geheimen Wert X.
    DHPrivateKey privateKey = (DHPrivateKey) keyPair.getPrivate();
    BigInteger x = privateKey.getX();

    //Erhalten Sie öffentlichen Wert Y.
    DHPublicKey publicKey = (DHPublicKey) keyPair.getPublic();
    BigInteger y = publicKey.getY();

4. Bob erhält den geheimen Wert X und den öffentlichen Wert Y.

Bob erhält den geheimen Wert X und den öffentlichen Wert Y. Die Erfassungsmethode ist dieselbe wie bei Alice.

Fünf. Alice und Bob tauschen öffentlichen Wert Y aus

Alice und Bob tauschen den veröffentlichten Wert Y aus. Zu diesem Zeitpunkt kann der Wert von Y von einem Dritten gesehen werden.

6. Alice generiert einen gemeinsamen Schlüssel

Alice generiert einen gemeinsamen Schlüssel. Verwenden Sie zum Generieren des gemeinsamen Schlüssels die Werte von P und G, den öffentlichen Wert Y der anderen Partei (Bob) und den privaten Schlüssel (DHPrivateKey) von Ihnen (Alice).

    public SecretKey generateKey(BigInteger p, BigInteger g, BigInteger othersY, DHPrivateKey myPrivateKey)
            throws GeneralSecurityException {

        //Generieren Sie den öffentlichen Schlüssel der anderen Partei (Bob)
        DHPublicKeySpec publicKeySpec = new DHPublicKeySpec(othersY, p, g);
        KeyFactory keyFactory = KeyFactory.getInstance("DiffieHellman");
        DHPublicKey othersPublicKey = (DHPublicKey) keyFactory.generatePublic(publicKeySpec);

        //Generieren Sie einen gemeinsamen Schlüssel mit dem öffentlichen Schlüssel der anderen Partei (Bob) und dem privaten Schlüssel Ihrer Person (Alice).
        KeyAgreement keyAgreement = KeyAgreement.getInstance("DiffieHellman");
        keyAgreement.init(myPrivateKey);
        keyAgreement.doPhase(othersPublicKey, true);
        SecretKey key = keyAgreement.generateSecret("AES");

        return key;
    }

7. Bob generiert einen gemeinsamen Schlüssel

Bob generiert einen gemeinsamen Schlüssel. Es wird auf die gleiche Weise wie Alice generiert, verwendet jedoch den öffentlichen Wert Y von Alice und den privaten Schlüssel von Bob (DHPrivateKey).

PBE -Password Based Encryption-

Was ist PBE?

PBE ist eine Technologie zum Schutz der Vertraulichkeit mithilfe von Passwörtern. Es hat die folgenden Funktionen.

Wie benutzt man PBE?

Salzgewinnung

Bereiten Sie das Salz vor, bevor Sie den Schlüssel generieren. Salt ist ein zufälliges Byte-Array. Salt wird verwendet, um zu verhindern, dass Passwörter durch Wörterbuchangriffe geknackt werden.

    public byte[] generateSalt() {
        SecureRandom random = new SecureRandom();
        byte[] salt = new byte[8];
        random.nextBytes(salt);

        return salt;
    }

Schlüsselgenerierung

Dies ist die Methode zum Generieren des PBE-Schlüssels (Common Key). Geben Sie das Passwort, Salt und die Anzahl der Hashings an. Durch Erhöhen der Anzahl der Hashings können Sie die für Brute Force Attack erforderliche Verarbeitungszeit erhöhen.

    public SecretKey generateKey(String password, byte[] salt, int hashCount) throws GeneralSecurityException {

        PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, hashCount);
        SecretKeyFactory keyFac = SecretKeyFactory.getInstance("PBEWithHmacSHA256AndAES_128");
        SecretKey key = keyFac.generateSecret(keySpec);

        keySpec.clearPassword();

        return key;
    }

Speichern von Algorithmusparametern

Holen Sie sich die Algorithmusparameter als Byte-Array und speichern Sie sie. Werte wie der Initialisierungsvektor werden in den Algorithmusparametern gespeichert.

    private byte[] getAlgorithmParameters(SecretKey key) throws GeneralSecurityException, IOException {

        Cipher encrypter = Cipher.getInstance("PBEWithHmacSHA256AndAES_128");
        encrypter.init(Cipher.ENCRYPT_MODE, key);
        AlgorithmParameters params = encrypter.getParameters();

        return params.getEncoded();
    }

Nachrichtenverschlüsselung

So verschlüsseln Sie die Nachricht. Geben Sie die allgemeinen Schlüssel- und Algorithmusparameter an.

    public byte[] encrypto(String plainText, SecretKey key, byte[] algParam)
            throws GeneralSecurityException, IOException {

        AlgorithmParameters params = AlgorithmParameters.getInstance("PBEWithHmacSHA256AndAES_128");
        params.init(algParam);

        Cipher encrypter = Cipher.getInstance("PBEWithHmacSHA256AndAES_128");
        encrypter.init(Cipher.ENCRYPT_MODE, key, params);

        return encrypter.doFinal(plainText.getBytes());
    }

Entschlüsselung des Codes

Dies ist die Methode zum Entschlüsseln des Codes. Geben Sie die allgemeinen Schlüssel- und Algorithmusparameter an.

    public String decrypto(byte[] cryptoText, SecretKey key, byte[] algParam)
            throws GeneralSecurityException, IOException {

        AlgorithmParameters params = AlgorithmParameters.getInstance("PBEWithHmacSHA256AndAES_128");
        params.init(algParam);

        Cipher decrypter = Cipher.getInstance("PBEWithHmacSHA256AndAES_128");
        decrypter.init(Cipher.DECRYPT_MODE, key, params);

        return new String(decrypter.doFinal(cryptoText));
    }

Am Ende

Hier ist eine Zusammenfassung dessen, was ich über Kryptographie gelernt habe, die aufgrund des Aufstiegs der Blockchain immer mehr Beachtung findet. Sie können sehen, dass Java verschiedene kryptografische Techniken abdeckt.

Recommended Posts

[Java] Verwenden Sie kryptografische Technologie mit Standardbibliotheken
Verwenden Sie OpenCV mit Java
Verwenden Sie PreparedStatement in Java
Verwenden Sie vorerst eine externe Java-Bibliothek
Versuchen Sie, mit Scala mithilfe der Standardbibliothek von Java Text zu einem Bild hinzuzufügen
Lesen Sie die Standardeingabe in Java
Versuchen Sie es mit globalem Hooking in Java mithilfe der JNativeHook-Bibliothek
Code, der verwendet werden soll, wenn Sie Json nur mit Standardbibliotheken in Java verarbeiten möchten
Greifen Sie mit Java auf die Netzwerkschnittstelle zu
Errate den Zeichencode in Java
Verwenden Sie Microsoft Graph mit Standard-Java
Geben Sie den Java-Speicherort in eclipse.ini an
Verschlüsselung mit RSA-Verschlüsselung in Java
Verwenden wir Twilio in Java! (Einführung)
Entpacken Sie die Zip-Datei in Java
[Java] Verwenden Sie nicht "+" im Anhang!
Verwenden Sie zusammengesetzte Schlüssel in Java Maps.
Verwenden Sie das Findbugs-Plugin in Eclipse
Willkommen im Sumpf der Java-Bibliotheken! !!
Analysieren der COTOHA-API-Syntaxanalyse in Java
Wie verwende ich Klassen in Java?
Verwenden Sie Stream in Java?
Rufen Sie die Super-Methode in Java auf
Erstellen Sie einen einfachen Webserver mit der Java-Standardbibliothek com.sun.net.httpserver
Holen Sie sich das Ergebnis von POST in Java
Mehrsprachige Unterstützung für Java Verwendung des Gebietsschemas
Verwenden Sie OpenCV_Contrib (ArUco) mit Java! (Teil 2-Programmierung)
[Java] Verwendung der File-Klasse
Java-Referenz zum Verständnis in der Abbildung
Versuchen Sie es mit der Stream-API in Java
Rufen Sie die Windows-Benachrichtigungs-API in Java auf
Java Artery - Einfach zu verwendende Unit-Test-Bibliothek
Ich habe das neue Yuan-Problem in Java ausprobiert
Studieren der Verwendung des Konstruktors (Java)
Notizen im Kopf organisieren (Java-Arrangement)
[Verarbeitung × Java] Verwendung der Schleife
Versuchen Sie, den CORBA-Dienst unter Java 11+ aufzurufen
Verwenden Sie "Rhino", das JavaScript in Java ausführt
Punkt 72: Bevorzugen Sie die Verwendung von Standardausnahmen
Was ist die Hauptmethode in Java?
[Verarbeitung × Java] Verwendung der Klasse
So erhalten Sie das Datum mit Java
Ich habe die AutoValue-Bibliothek mit Intellij ausprobiert
[Verarbeitung × Java] Verwendung der Funktion
Die Geschichte des Schreibens von Java in Emacs
Konsoleneingabe in Java (Verständnis des Mechanismus)
[Java] Färben Sie die Standardausgabe an das Terminal
[Java] Verwendung der Calendar-Klasse
Was war keine faire Verwendung der Java-API-Umleitung unter Android?
Ist es möglich, die Bibliothek (aar) in die Android-Bibliothek (aar) zu stellen und zu verwenden?
Verwenden Sie JDBC Manager mit den Einstellungen in jdbc.dicon.
Die Geschichte des einfachen String-Vergleichs in Java
[Java] Behandlung von Java Beans in der Methodenkette
Über die Verwirrung beim Starten von Java-Servern
Vorstellung der Bibliothek
Die Geschichte eines gewöhnlichen Othello in Java
Über die Idee anonymer Klassen in Java