In einem bestimmten Projekt war ich gezwungen, den mit OpenSSL cli mit verschiedenen Skriptsprachen verschlüsselten Text zu entschlüsseln, und es war im Fall von Java und PHP ein wenig problematisch, daher habe ich die Informationen zusammengefasst.
Mit OpenSSL cli können Sie beispielsweise Text einfach mit einem Kennworttempo verschlüsseln, indem Sie die unten gezeigte Option enc verwenden. Wenn Sie jedoch versuchen, dies mit Java zu entschlüsseln, werden OpenSSL-kompatible Headerinformationen hinzugefügt und analysiert. Es konnte nicht entschlüsselt werden, da es keine entsprechende Funktion gibt.
Wenn Sie den Inhalt einer Textdatei mit OpenSSL cli verschlüsseln, können Sie leicht eine verschlüsselte Zeichenfolge erhalten, indem Sie einfach die Verschlüsselungsmethode und das Kennwort als Optionen angeben, wie im folgenden Beispiel gezeigt.
cat plain.txt | openssl enc -e -aes-128-cbc -base64 -k <Passwort>
Wenn AES als Verschlüsselungsmethode angegeben ist, ist es normalerweise erforderlich, beim Ver- und Entschlüsseln zusätzlich zum Kennwort Salt und IV (Initialisierungsvektor) anzugeben, in OpenSSL jedoch dieses Salt und Die IV wird automatisch generiert und in den Header der verschlüsselten Daten eingebettet, sodass der Benutzer nur das Kennwort kennen muss. Wie Sie im Beispielskript in diesem Artikel sehen können, verfügt die OpenSSL-Bibliothek von Perl und Ruby über einen Salt- und IV-Generierungsmechanismus, der mit OpenSSL cli verschlüsselt ist, sodass die Verwendung von mit OpenSSL cli verschlüsseltem Text relativ einfach ist. Im Fall der OpenSSL-Bibliothek für Java und PHP war es jedoch erforderlich, den Salt- und IV-Generierungsmechanismus selbst zu integrieren, da dieser OpenSSL-CLI-kompatible Mechanismus nicht vorhanden war.
Übrigens, wenn die Verschlüsselung durch die AES-Methode unter Verwendung der enc-Option mit OpenSSL cli durchgeführt wird, hat Salt eine zufällige 8-Byte-Bitfolge (64 Bit) und IV hat 16 Bytes (16 Bytes), die mit der folgenden Methode generiert werden. 128 Bit) Bitfolge wird verwendet.
IV Generationsformel Schlüssel = Passwort + Salt MD5 IV = Schlüssel + Passwort + Salt MD5
Diese werden als Header-Informationen am Anfang der verschlüsselten Daten hinzugefügt und als verschlüsselte Daten zurückgegeben.
Zeichenkette "Salted __" (8 Bytes) + Salt (8 Bytes) + IV (16 Bytes) + [verschlüsselte Daten]
Wenn Sie beim Entschlüsseln bestätigen, dass der Anfang der verschlüsselten Daten "Salted__" ist, verwenden Sie die folgenden 8 Datenbytes als Salt und aus dem Kennwort Salt wie bei der Verschlüsselung Erzeugt eine IV und entschlüsselt den Körper der verschlüsselten Daten, die auf Salt folgen.
Der folgende Beispielcode wird durch Einbeziehen dieses Codes geschrieben.
Das getKeyAndGenerateIv
in diesem Code wird verwendet, um Salt und IV auf OpenSSL Cli-kompatible Weise zu generieren.
EncryptDecryptText.java
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import java.security.spec.KeySpec;
import java.security.SecureRandom;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Arrays;
import java.io.BufferedReader;
import java.io.InputStreamReader;
class EncryptDecryptText {
public static boolean getKeyAndGenerateIv(String password, byte[] salt, byte[] key_bytes, byte[] iv_bytes) {
try {
byte[] password_bytes = password.getBytes(StandardCharsets.UTF_8);
int length = password_bytes.length + salt.length;
ByteBuffer byte_buffer = ByteBuffer.allocate(length);
byte_buffer.put(password_bytes);
byte_buffer.put(salt);
byte_buffer.rewind();
byte[] byte_array = new byte[length];
byte_buffer.get(byte_array);
System.arraycopy(MessageDigest.getInstance("MD5").digest(byte_array), 0, key_bytes, 0, key_bytes.length);
length = password_bytes.length + salt.length + key_bytes.length;
byte_buffer = ByteBuffer.allocate(length);
byte_buffer.put(key_bytes);
byte_buffer.put(password_bytes);
byte_buffer.put(salt);
byte_buffer.rewind();
byte_array = new byte[length];
byte_buffer.get(byte_array);
System.arraycopy(MessageDigest.getInstance("MD5").digest(byte_array), 0, iv_bytes, 0, iv_bytes.length);
}
catch ( NoSuchAlgorithmException e ) {
return false;
}
return true;
}
public static String encrypt(String plaintext, String password) throws Exception {
// Generate random salt.
byte[] random_bytes = new byte[8];
new SecureRandom().nextBytes(random_bytes);
byte[] key_bytes = new byte[16];
byte[] iv_bytes = new byte[16];
getKeyAndGenerateIv(password, random_bytes, key_bytes, iv_bytes);
SecretKey secret = new SecretKeySpec(key_bytes, "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv_bytes);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret, ivspec);
byte[] encrypted_bytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
final String header_string = "Salted__";
byte[] header_bytes = header_string.getBytes(StandardCharsets.UTF_8);
int length = header_bytes.length + random_bytes.length + encrypted_bytes.length;
ByteBuffer byte_buffer = ByteBuffer.allocate(length);
byte_buffer.put(header_bytes);
byte_buffer.put(random_bytes);
byte_buffer.put(encrypted_bytes);
byte_buffer.rewind();
byte[] byte_array = new byte[length];
byte_buffer.get(byte_array);
return new String(Base64.getEncoder().encodeToString(byte_array));
}
public static String decrypt(String payload, String password) throws Exception {
byte[] payload_bytes = Base64.getDecoder().decode(payload.getBytes(StandardCharsets.UTF_8));
byte[] header_bytes = new byte[8];
byte[] salt_bytes = new byte[8];
int length = payload_bytes.length;
ByteBuffer byte_buffer = ByteBuffer.allocate(length);
byte_buffer.put(payload_bytes);
byte_buffer.rewind();
byte_buffer.get(header_bytes);
byte_buffer.get(salt_bytes);
length = payload_bytes.length - header_bytes.length - salt_bytes.length;
byte[] data_bytes = new byte[length];
byte_buffer.get(data_bytes);
byte[] key_byte = new byte[16];
byte[] iv_bytes = new byte[16];
getKeyAndGenerateIv(password, salt_bytes, key_byte, iv_bytes);
SecretKey secret = new SecretKeySpec(key_byte, "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv_bytes);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, ivspec);
byte[] decrypted = cipher.doFinal(data_bytes);
return new String(decrypted);
}
public static void main(String[] args) throws Exception {
//Lesen Sie die zu verschlüsselnden Daten / Passwörter
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Plain text: ");
System.out.flush();
String plain_text = br.readLine();
System.out.print("Password: ");
System.out.flush();
String password = br.readLine();
//Verschlüsselungsprozess
String encrypted = EncryptorDecryptor.encrypt(plain_text, password);
System.out.print("encrypted:" + encrypted);
System.out.println();
//Entschlüsselungsprozess
String decrypted = EncryptorDecryptor.decrypt(encrypted, password);
System.out.print("decrypted:" + decrypted);
System.out.println();
}
}
python
<?php
function encrypt($plain_text, $password) {
//Generieren Sie ein zufälliges 8-Byte-Salz
$random_salt = openssl_random_pseudo_bytes(8);
//Generieren Sie Schlüssel und IV aus Passwort und Salt
$key_data = $password.$random_salt;
$raw_key = md5($key_data, true);
$iv_data = $raw_key.$password.$random_salt;
$iv = md5($iv_data, true);
//Verschlüsselung
$encrypted = openssl_encrypt($plain_text, 'aes-128-cbc', $raw_key, OPENSSL_RAW_DATA, $iv);
return ( base64_encode("Salted__".$random_salt.$encrypted) );
}
function decrypt($encrypted_text, $password) {
//Entschlüsselung
$payload_text = base64_decode($encrypted_text);
$header = substr($payload_text, 0, 7);
$salt = substr($payload_text, 8, 8);
$data = substr($payload_text, 16);
//Generieren Sie Schlüssel und IV aus Passwort und Salt
$key_data = $password.$salt;
$raw_key = md5($key_data, true);
$iv_data = $raw_key.$password.$salt;
$iv = md5($iv_data, true);
$decrypted_text = openssl_decrypt($data, 'aes-128-cbc', $raw_key, OPENSSL_RAW_DATA, $iv);
return ( $decrypted_text );
}
// Usage:
$str = file_get_contents('php://stdin');
print "Plain text: " . $str . "\n";
$password = $argv[1];
print "Password: " . $password . "\n";
//Verschlüsselungsprozess
$encrypted = encrypt($str, $password);
print "encrypted:" . $encrypted . "\n";
//Entschlüsselungsprozess
$decrypted = decrypt($encrypted, $password);
print "decrypted:" . $decrypted . "\n";
python
#!/usr/bin/perl
use MIME::Base64;
use strict;
use Crypt::CBC;
use Config;
sub encrypt {
my ($plain_text, $passphrase) = @_;
my $pbe = Crypt::CBC->new(
-key => $passphrase,
-cipher => 'Crypt::Rijndael',
-keysize => 128/8,
);
my $cipher_text = $pbe->encrypt($plain_text);
my $encrypted_text = encode_base64($cipher_text);
return $encrypted_text;
}
sub decrypt {
my ($encrypted_text, $passphrase) = @_;
my $cipher_text = decode_base64($encrypted_text);
my $pbe = Crypt::CBC->new(
-key => $passphrase,
-cipher => 'Crypt::Rijndael',
-keysize => 128/8,
);
my $plain_text = $pbe->decrypt($cipher_text);
return $plain_text;
}
# Usage:
#Verschlüsselungsprozess
my $str = (scalar <>);
print "Plain text: " . $str . "\n";
my $password = $ARGV[0];
print "Password: " . $password . "\n";
#Verschlüsselungsprozess
my $encrypted = encrypt($str, $password);
print "encrypted:" . $encrypted . "\n";
#Entschlüsselungsprozess
my $decrypted = decrypt($encrypted, $password);
print "decrypted:" . $decrypted . "\n";
python
#!/usr/bin/ruby
require "openssl"
require "base64"
def encrypt(plain_text, password)
salt = OpenSSL::Random.random_bytes(8)
cipher = OpenSSL::Cipher.new("aes-128-cbc")
cipher.encrypt()
cipher.pkcs5_keyivgen(
password,
salt,
1
)
#Im Fall von Ruby müssen Sie die Header-Informationen selbst zur Zeichenfolge hinzufügen.
encrypted_text = "Salted__" + salt + cipher.update(plain_text) + cipher.final
return Base64.encode64(encrypted_text)
end
def decrypt(encrypted_text, password)
decoded_str = Base64.decode64(encrypted_text)
#Im Fall von Ruby müssen Sie die Header-Informationen auch selbst zerlegen
@cipher_text = decoded_str.unpack("a8a8a*")
cipher = OpenSSL::Cipher.new("aes-128-cbc")
cipher.pkcs5_keyivgen(
password,
@cipher_text[1],
1
)
cipher.decrypt()
decrypted_text = cipher.update(@cipher_text[2]) + cipher.final
return decrypted_text
end
# Usage:
str = gets
print "Plain text: " + str + "\n";
password = ARGV[0]
print "Password: " + password + "\n";
#Verschlüsselungsprozess
encrypted = encrypt(str, password);
print "encrypted:" + encrypted + "\n";
#Entschlüsselungsprozess
decrypted = decrypt(encrypted, password);
print "decrypted:" + decrypted + "\n";
python
#!/bin/bash
function encrypt() {
plain_text=$1
password=$2
encrypted_text=`echo -n "$plain_text" | openssl enc -e -aes-128-cbc -base64 -k "$password"`
echo $encrypted_text
}
function decrypt() {
encrypted_text=$1
password=$2
plain_text=`echo "$encrypted_text" | openssl enc -d -aes-128-cbc -base64 -k "$password"`
echo $plain_text
}
# Useage:
str="$(cat -)"
echo "Plain text: $str"
password=$1
echo "Password: $password"
#Verschlüsselungsprozess
encrypted=`encrypt "$str" "$password"`
echo "encrypted:$encrypted"
#Entschlüsselungsprozess
decrypted=`decrypt "$encrypted" "$password"`
echo "decrypted:$decrypted"
Recommended Posts