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.
Symmetrische Verschlüsselung ist eine Technologie zum Schutz der Vertraulichkeit von Nachrichten. Es hat die folgenden Funktionen.
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();
}
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);
}
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());
}
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));
}
Die Verschlüsselung mit öffentlichen Schlüsseln ist eine Technologie zum Schutz der Vertraulichkeit von Nachrichten. Es hat die folgenden Funktionen.
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();
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());
}
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));
}
Die Einweg-Hash-Funktion ist eine Technik zum Erkennen von Nachrichtenmanipulationen. Es hat die folgenden Funktionen.
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());
}
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);
}
Der Nachrichtenauthentifizierungscode (MAC) ist eine Technologie zum Erkennen von Nachrichtenmanipulationen und "Spoofing". Es hat die folgenden Funktionen.
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();
}
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());
}
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);
}
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
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();
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();
}
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);
}
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.
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.
Befolgen Sie die oben beschriebenen Schritte, um den Schlüsselaustausch zu erläutern.
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
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();
}
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();
Bob erhält den geheimen Wert X und den öffentlichen Wert Y. Die Erfassungsmethode ist dieselbe wie bei Alice.
Alice und Bob tauschen den veröffentlichten Wert Y aus. Zu diesem Zeitpunkt kann der Wert von Y von einem Dritten gesehen werden.
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;
}
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-
PBE ist eine Technologie zum Schutz der Vertraulichkeit mithilfe von Passwörtern. Es hat die folgenden Funktionen.
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;
}
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;
}
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();
}
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());
}
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));
}
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