Kryptographie & Kryptologie
12.10.2023 um 02:00
Okay, derzeit bin ich an einem neuen Algorithmus dran.
Deswegen gibt es hier und jetzt den Code zum letzten Rätsel:
public class Encryptor
{
private static final int tagLengthBit = 128;
private static final int ivLengthByte = 12;
private static final int saltLengthByte = 16;
private static final String encryptAlgo = "AES/GCM/NoPadding";
// Encryption System - Return A Base64 Encoded 256bit AES Encrypted Text
public static String Encrypt(byte[] plainText, String password) throws Exception
{
// 16 byte salt
byte[] salt = CryptoUtils.GetRandomNonce(saltLengthByte);
// GCM recommended 12 bytes iv ?
byte[] iv = CryptoUtils.GetRandomNonce(ivLengthByte);
// secret key from password
SecretKey secretKey = CryptoUtils.GetAESKeyFromPassword(password.toCharArray(), salt);
Cipher cipher = Cipher.getInstance(encryptAlgo);
// AES-GCM needs GCMParameterSppec
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(tagLengthBit, iv));
byte[] cipherText = cipher.doFinal(plainText);
// prefix iv and salt to cypher text
byte[] cipherTextWithIvSalt = ByteBuffer.allocate(iv.length + salt.length + cipherText.length)
.put(iv)
.put(salt)
.put(cipherText)
.array();
// string representation, base64, send this string to other for decryption
return Base64.getEncoder().encodeToString(cipherTextWithIvSalt);
}
}
Da denkt ihr jetzt wahrscheinlich, was is'n daran besonders?
Das:
public class METGUI extends javax.swing.JFrame
{
private static final long serialVersionUID = 1L;
private static final String P01 = "~pCq;FNo5L?k?em;y/^Jb"; private static final String P02 = "5v8z57öz1+n52z=vfcj80";
private static final String P03 = "0n~cYsgkpTtKOMGr%-')4"; private static final String P04 = "*[NUk|^W7[c^EG)L2ZF>t";
private static final String P05 = "8vb^jp%^kU1y.<QI8}pTw"; private static final String P06 = "lbb@KBtr?3&.iiMUU(VM-";
private static final String P07 = "=rAx6F,lqYxv~8p>8h(C="; private static final String P08 = "w(l!8jQ(/54lpM6FlDwkC";
private static final String P09 = "56v22j8x^cc^n5jx15dcf"; private static final String P10 = "zR9Y9TfxttlxDD%sT`48{";
private static final String P11 = "Q1e`BF0c1f}X(mb@hfTv9"; private static final String P12 = "a6g1cXu0+oKpxXI>%X#gm";
private static final String P13 = "8*=pZ%xoy[!d!1kR:H(8h"; private static final String P14 = "An-Vn}Tk'V*mP`m3D&C,f";
private static final String P15 = "qA%^O90(,B)d)ln~ctNcI"; private static final String P16 = "Xa~]QU9SA1JPMQ<h=Fj8O";
private static final String P17 = "2?K]E.;*X+XhFZJmq:JXY"; private static final String P18 = "8G,Eav_&W'/i]$R,|WkK4";
private static final String P19 = "?'gFi*lWHWBHQT*JBnOE!"; private static final String P20 = "|3>y46_SkO>cw+{'o[Om-";
private static final String specPassword = "^E$Ii^Df@2Gx*2*q6+'wP";
private static final String masterPassword = "?|dd|6h*%cWFTG@`*)€)~";
private static String password = masterPassword;
private static final String ok = "The user has not abused the Tool.";
private static final String bad = "The user has abused the Tool.";
private static final String check = "Do not delete this file!";
private static final Charset UTF_8 = StandardCharsets.UTF_8;
private int grx2;
public METGUI() throws Exception
{
grx2 = 0;
ARB();
initComponents();
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
FileChooser = new javax.swing.JFileChooser();
jPanel1 = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
Input = new javax.swing.JTextArea();
jPanel2 = new javax.swing.JPanel();
jScrollPane2 = new javax.swing.JScrollPane();
Output = new javax.swing.JTextArea();
Clear = new javax.swing.JButton();
AES = new javax.swing.JPanel();
Encrypt = new javax.swing.JButton();
Decrypt = new javax.swing.JButton();
Unique = new javax.swing.JPanel();
UniqueEncrypt = new javax.swing.JButton();
UniqueDecrypt = new javax.swing.JButton();
CopyInputButton = new javax.swing.JButton();
CopyOutputButton = new javax.swing.JButton();
PasteClipboardButton = new javax.swing.JButton();
InputCharsButton = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();
jLabel1 = new javax.swing.JLabel();
InputCharsNum = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
OutputCharsNum = new javax.swing.JLabel();
jMenuBar1 = new javax.swing.JMenuBar();
FileMenu = new javax.swing.JMenu();
OpenFile = new javax.swing.JMenuItem();
jSeparator4 = new javax.swing.JPopupMenu.Separator();
SaveInput = new javax.swing.JMenuItem();
SaveOutput = new javax.swing.JMenuItem();
jSeparator3 = new javax.swing.JPopupMenu.Separator();
Exit = new javax.swing.JMenuItem();
EditMenu = new javax.swing.JMenu();
CopyInputMenuItem = new javax.swing.JMenuItem();
CopyOutputMenuItem = new javax.swing.JMenuItem();
jSeparator1 = new javax.swing.JPopupMenu.Separator();
PasteClipboardMenuItem = new javax.swing.JMenuItem();
jSeparator2 = new javax.swing.JPopupMenu.Separator();
ChangeMasterPassword = new javax.swing.JMenuItem();
ShowMasterPassword = new javax.swing.JMenuItem();
ResetMasterPassword = new javax.swing.JMenuItem();
InfoMenu = new javax.swing.JMenu();
AboutMenuItem = new javax.swing.JMenuItem();
HelpMenuItem = new javax.swing.JMenuItem();
FileChooser.setCurrentDirectory(new java.io.File("C:\\"));
FileChooser.setDialogTitle("Choose file...");
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Input", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.BELOW_TOP));
Input.setColumns(20);
Input.setLineWrap(true);
Input.setRows(5);
Input.setWrapStyleWord(true);
jScrollPane1.setViewportView(Input);
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 315, Short.MAX_VALUE)
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 521, Short.MAX_VALUE)
);
jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Output", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.BELOW_TOP));
Output.setEditable(false);
Output.setColumns(20);
Output.setLineWrap(true);
Output.setRows(5);
Output.setWrapStyleWord(true);
jScrollPane2.setViewportView(Output);
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 315, Short.MAX_VALUE)
);
jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane2)
);
Clear.setText("Clear Textfields");
Clear.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
ClearActionPerformed(evt);
}
});
AES.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "AES 256 Bit", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.BELOW_TOP));
Encrypt.setText("Encrypt");
Encrypt.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
EncryptActionPerformed(evt);
}
});
Decrypt.setText("Decrypt");
Decrypt.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
DecryptActionPerformed(evt);
}
});
javax.swing.GroupLayout AESLayout = new javax.swing.GroupLayout(AES);
AES.setLayout(AESLayout);
AESLayout.setHorizontalGroup(
AESLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(AESLayout.createSequentialGroup()
.addGap(18, 18, 18)
.addGroup(AESLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(AESLayout.createSequentialGroup()
.addComponent(Decrypt)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGroup(AESLayout.createSequentialGroup()
.addComponent(Encrypt, javax.swing.GroupLayout.DEFAULT_SIZE, 71, Short.MAX_VALUE)
.addGap(20, 20, 20))))
);
AESLayout.setVerticalGroup(
AESLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(AESLayout.createSequentialGroup()
.addContainerGap()
.addComponent(Encrypt)
.addGap(18, 18, 18)
.addComponent(Decrypt)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
Unique.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Unique ~7250 Bit", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.BELOW_TOP));
Unique.setMinimumSize(new java.awt.Dimension(121, 101));
UniqueEncrypt.setText("Encrypt");
UniqueEncrypt.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
UniqueEncryptActionPerformed(evt);
}
});
UniqueDecrypt.setText("Decrypt");
UniqueDecrypt.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
UniqueDecryptActionPerformed(evt);
}
});
javax.swing.GroupLayout UniqueLayout = new javax.swing.GroupLayout(Unique);
Unique.setLayout(UniqueLayout);
UniqueLayout.setHorizontalGroup(
UniqueLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(UniqueLayout.createSequentialGroup()
.addGap(18, 18, 18)
.addGroup(UniqueLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(UniqueDecrypt, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(UniqueEncrypt, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
UniqueLayout.setVerticalGroup(
UniqueLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(UniqueLayout.createSequentialGroup()
.addContainerGap()
.addComponent(UniqueEncrypt)
.addGap(18, 18, 18)
.addComponent(UniqueDecrypt)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
CopyInputButton.setText("Copy Input");
CopyInputButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
CopyInputButtonActionPerformed(evt);
}
});
CopyOutputButton.setText("Copy Output");
CopyOutputButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
CopyOutputButtonActionPerformed(evt);
}
});
PasteClipboardButton.setText("Paste Clipboard");
PasteClipboardButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
PasteClipboardButtonActionPerformed(evt);
}
});
InputCharsButton.setText("Input Chars");
InputCharsButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
InputCharsButtonActionPerformed(evt);
}
});
jButton2.setText("Output Chars");
jButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton2ActionPerformed(evt);
}
});
jLabel1.setText("Input Chars:");
jLabel1.setMaximumSize(new java.awt.Dimension(69, 14));
jLabel1.setMinimumSize(new java.awt.Dimension(69, 14));
jLabel1.setPreferredSize(new java.awt.Dimension(69, 14));
InputCharsNum.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
InputCharsNum.setText("0");
jLabel3.setText("Output Chars:");
OutputCharsNum.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
OutputCharsNum.setText("0");
FileMenu.setText("File");
OpenFile.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F, java.awt.event.InputEvent.ALT_MASK));
OpenFile.setText("Open File");
OpenFile.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
OpenFileActionPerformed(evt);
}
});
FileMenu.add(OpenFile);
FileMenu.add(jSeparator4);
SaveInput.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_I, java.awt.event.InputEvent.ALT_MASK));
SaveInput.setText("Save Input");
SaveInput.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
SaveInputActionPerformed(evt);
}
});
FileMenu.add(SaveInput);
SaveOutput.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.ALT_MASK));
SaveOutput.setText("Save Output");
SaveOutput.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
SaveOutputActionPerformed(evt);
}
});
FileMenu.add(SaveOutput);
FileMenu.add(jSeparator3);
Exit.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_E, java.awt.event.InputEvent.ALT_MASK));
Exit.setText("Exit");
Exit.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
ExitActionPerformed(evt);
}
});
FileMenu.add(Exit);
jMenuBar1.add(FileMenu);
EditMenu.setText("Edit");
CopyInputMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_I, java.awt.event.InputEvent.CTRL_MASK));
CopyInputMenuItem.setText("Copy Input to Clipboard");
CopyInputMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
CopyInputMenuItemActionPerformed(evt);
}
});
EditMenu.add(CopyInputMenuItem);
CopyOutputMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.CTRL_MASK));
CopyOutputMenuItem.setText("Copy Output to Clipboard");
CopyOutputMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
CopyOutputMenuItemActionPerformed(evt);
}
});
EditMenu.add(CopyOutputMenuItem);
EditMenu.add(jSeparator1);
PasteClipboardMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_V, java.awt.event.InputEvent.CTRL_MASK));
PasteClipboardMenuItem.setText("Paste from Clipboard to Input");
PasteClipboardMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
PasteClipboardMenuItemActionPerformed(evt);
}
});
EditMenu.add(PasteClipboardMenuItem);
EditMenu.add(jSeparator2);
ChangeMasterPassword.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_E, java.awt.event.InputEvent.CTRL_MASK));
ChangeMasterPassword.setText("Change Master Password");
ChangeMasterPassword.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
ChangeMasterPasswordActionPerformed(evt);
}
});
EditMenu.add(ChangeMasterPassword);
ShowMasterPassword.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
ShowMasterPassword.setText("Show Master Password");
ShowMasterPassword.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
ShowMasterPasswordActionPerformed(evt);
}
});
EditMenu.add(ShowMasterPassword);
ResetMasterPassword.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_R, java.awt.event.InputEvent.CTRL_MASK));
ResetMasterPassword.setText("Reset Master Password");
ResetMasterPassword.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
ResetMasterPasswordActionPerformed(evt);
}
});
EditMenu.add(ResetMasterPassword);
jMenuBar1.add(EditMenu);
InfoMenu.setText("Info");
AboutMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_A, java.awt.event.InputEvent.CTRL_MASK));
AboutMenuItem.setText("About");
AboutMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
AboutMenuItemActionPerformed(evt);
}
});
InfoMenu.add(AboutMenuItem);
HelpMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_H, java.awt.event.InputEvent.CTRL_MASK));
HelpMenuItem.setText("Help");
HelpMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
HelpMenuItemActionPerformed(evt);
}
});
InfoMenu.add(HelpMenuItem);
jMenuBar1.add(InfoMenu);
setJMenuBar(jMenuBar1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(AES, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(Unique, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(Clear, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(CopyInputButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(CopyOutputButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(PasteClipboardButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(InputCharsButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jButton2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(InputCharsNum, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel3)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(OutputCharsNum, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(21, 21, 21)
.addComponent(AES, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(Unique, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(CopyInputButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(CopyOutputButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(PasteClipboardButton)
.addGap(18, 18, 18)
.addComponent(Clear)
.addGap(18, 18, 18)
.addComponent(InputCharsButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(InputCharsNum))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jButton2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel3)
.addComponent(OutputCharsNum))
.addGap(0, 0, Short.MAX_VALUE))
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGap(20, 20, 20))
);
pack();
}// </editor-fold>
// Security Check
private void ARB()
{
try
{
File file = new File("C:\\MET\\MET.dat");
FileInputStream ft = new FileInputStream(file);
String temp;
try (DataInputStream in = new DataInputStream(ft))
{
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
temp = reader.readLine();
}
String erf = Decryptor.Decrypt(temp, specPassword);
if(erf.equals(check) || erf.equals(ok))
{
WriteToFile(0, ok);
}
else
System.exit(0);
}
catch(Exception ex)
{
javax.swing.JOptionPane.showMessageDialog(null, "An Error occured: " + ex, "Error", javax.swing.JOptionPane.ERROR_MESSAGE);
}
}
// Write To File
private void WriteToFile(int element, String text) throws IOException, Exception
{
BufferedWriter writer;
switch(element)
{
case 0:
String temp = Encryptor.Encrypt(text.getBytes(UTF_8), specPassword);
writer = new BufferedWriter(new FileWriter("MET.dat"));
writer.write(temp);
writer.close();
break;
case 1:
writer = new BufferedWriter(new FileWriter("Input.txt"));
writer.write(Input.getText());
writer.close();
break;
case 2:
writer = new BufferedWriter(new FileWriter("Output.txt"));
writer.write(Output.getText());
writer.close();
break;
}
}
// Copy/Paste Function
private void CopyPaste(int option)
{
StringSelection stringSelection;
Clipboard clipboard;
Transferable transfer;
switch(option)
{
case 1:
stringSelection = new StringSelection(Input.getText());
clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(stringSelection, null);
break;
case 2:
stringSelection = new StringSelection(Output.getText());
clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(stringSelection, null);
break;
case 3:
clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
transfer = clipboard.getContents(this);
if(transfer == null)
{
return;
}
try
{
Input.setText((String)transfer.getTransferData(DataFlavor.stringFlavor));
CountInputChars();
}
catch(UnsupportedFlavorException | IOException ex)
{
Output.setText("An Error occured: " + ex);
}
}
}
// Count Input Chars
private void CountInputChars()
{
this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
int inputCounter = Input.getText().length();
InputCharsNum.setText("" + inputCounter);
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
// Count Output Chars
private void CountOutputChars()
{
this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
int outputCounter = Output.getText().length();
OutputCharsNum.setText("" + outputCounter);
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
// AES Encrypt Button
private void EncryptActionPerformed(java.awt.event.ActionEvent evt) {
this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
try
{
if(!Input.getText().isEmpty())
{
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
Output.setText(Encryptor.Encrypt(Input.getText().getBytes(UTF_8), password));
}
else
{
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
javax.swing.JOptionPane.showMessageDialog(null, "There is no Text to encrypt!", "Error", javax.swing.JOptionPane.ERROR_MESSAGE);
}
}
catch(Exception ex)
{
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
Output.setText("An Error occured: " + ex.toString());
}
Output.setCaretPosition(0);
CountInputChars();
CountOutputChars();
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
// AES Decrypt Button
private void DecryptActionPerformed(java.awt.event.ActionEvent evt) {
this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
try
{
String test = Input.getText();
if(!test.isEmpty())
Output.setText(Decryptor.Decrypt(test, password));
else
{
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
javax.swing.JOptionPane.showMessageDialog(null, "There is no Text to decrypt!", "Error", javax.swing.JOptionPane.ERROR_MESSAGE);
}
}
catch(Exception ex)
{
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
Output.setText("An Error occured: " + ex.toString());
grx2++;
}
if(grx2 >= 5)
{
try
{
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
WriteToFile(0, bad);
System.exit(0);
}
catch (Exception ex)
{
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
javax.swing.JOptionPane.showMessageDialog(null, "An Error occured: " + ex.toString());
}
}
Output.setCaretPosition(0);
CountOutputChars();
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
// Clear Button
private void ClearActionPerformed(java.awt.event.ActionEvent evt) {
Input.setText("");
Output.setText("");
CountInputChars();
CountOutputChars();
}
// Copy Input To Clipboard
private void CopyInputMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
CopyPaste(1);
CountInputChars();
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
// Copy Output To Clipboard
private void CopyOutputMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
CopyPaste(2);
CountOutputChars();
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
// Paste From Clipboard To Input
private void PasteClipboardMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
CopyPaste(3);
CountInputChars();
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
// Info About The Program Version And Author
private void AboutMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
javax.swing.JOptionPane.showMessageDialog(null, "MET Message Encryption Tool (c) version 1.0\n\n"
+ "Author: Thanius", "Info...", javax.swing.JOptionPane.INFORMATION_MESSAGE);
}
// Change Master Password
private void ChangeMasterPasswordActionPerformed(java.awt.event.ActionEvent evt) {
String temp = null;
try
{
temp = javax.swing.JOptionPane.showInputDialog(null, "Please enter the "
+ "new Master Password for AES:\n\nIt must contain min. 21 chars "
+ "and max. 512 chars.\n");
}
catch(HeadlessException ex)
{
javax.swing.JOptionPane.showMessageDialog(null, "An error occured,\nthe Password isn't changed:\n\n" + ex, "ERROR", javax.swing.JOptionPane.ERROR_MESSAGE);
}
if(temp == null)
{
//javax.swing.JOptionPane.showMessageDialog(null, "Input is empty!", "ERROR", javax.swing.JOptionPane.ERROR_MESSAGE);
}
else if(temp.length() < 21 || temp.length() > 512)
{
javax.swing.JOptionPane.showMessageDialog(null, "The new Master Password is too short/long!\n"
+ "The Master Password wasn't changed!", "ERROR", javax.swing.JOptionPane.ERROR_MESSAGE);
}
else
{
password = temp;
}
}
// Show Master Password
private void ShowMasterPasswordActionPerformed(java.awt.event.ActionEvent evt) {
if(password.equals(masterPassword))
{
javax.swing.JOptionPane.showMessageDialog(null, "The original Master Password cannot be displayed!\nOnly a changed Password can be shown.", "ERROR", javax.swing.JOptionPane.ERROR_MESSAGE);
}
else
{
Output.setText(password);
}
}
// Reset Master Password
private void ResetMasterPasswordActionPerformed(java.awt.event.ActionEvent evt) {
password = masterPassword;
javax.swing.JOptionPane.showMessageDialog(null, "Password reset successful.", "Password Reset", javax.swing.JOptionPane.INFORMATION_MESSAGE);
}
// Help
private void HelpMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
Output.setText(""
+ "********************************************************\n"
+ " HELP\n"
+ "°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°\n\n"
+ "********************************************************\n"
+ " FUNCTIONS\n"
+ "________________________________________\n\n"
+ "Encrypt AES & Unique:\n"
+ "°°°°°°°°°°°°°°°°°°°°°°°°°\n"
+ "Encrypts the Text in the Input Textfield and shows\n"
+ "the encrypted Text in the Output Textfield.\n\n"
+ "Decrypt AES & Unique:\n"
+ "°°°°°°°°°°°°°°°°°°°°°°°°°\n"
+ "Decrypts the Text in the Input Textfield and shows\n"
+ "the decrypted Text in the Output Textfield.\n\n"
+ "Copy Input to Clipboard:\n"
+ "°°°°°°°°°°°°°°°°°°°°°°°°°°°\n"
+ "Copy the Text in the Input Textfield to the Clipboard.\n"
+ "(For the use in other programs)\n\n"
+ "Copy Output to Clipboard:\n"
+ "°°°°°°°°°°°°°°°°°°°°°°°°°°°°°\n"
+ "Copy the Text in the Output Textfield to the Clipboard.\n"
+ "(For the use in other programs)\n\n"
+ "Paste from Clipboard to Input:\n"
+ "°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°\n"
+ "Paste the Text stored in the Clipboard to the Input Textfield.\n\n"
+ "Change Master Password:\n"
+ "°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°\n"
+ "Enter a new Master Password for better security.\n"
+ "(AES only)\n"
+ "You have to write down this password if you encrypt "
+ "a message with a new Master Password, otherwise "
+ "you won't be able to decrypt the encrypted Message.\n"
+ "The program don't save the changed Master Password "
+ "if you close the program, to ensure safety.\n\n"
+ "Show Master Password:\n"
+ "°°°°°°°°°°°°°°°°°°°°°°°°°°°\n"
+ "Shows the changed Master Password.\nThe original "
+ "Master Password will not show up.\n\n"
+ "Reset Master Password:\n"
+ "°°°°°°°°°°°°°°°°°°°°°°°°°°°°\n"
+ "Restore the original Master Password.\n"
+ "The original Master Password will be restored"
+ " on closing the program too.\n\n\n"
+ "********************************************************\n"
+ " HOW TO USE THIS TOOL PROPERLY ?\n"
+ "________________________________________\n\n"
+ "ENCRYPTION & DECRYPTION:\n\n"
+ "AES - Encryption:\n"
+ "°°°°°°°°°°°°°°°°°°°\n"
+ "This Tool works with a Master Password.\n"
+ "The Master Password is necessary to make a unique "
+ "AES Encryption.\n"
+ "The Password must be at minimum 21 chars and "
+ "at maximum 512 chars long, any character is allowed.\n"
+ "You can use the \"KGMET.jar\" Keygen,\n"
+ "(can be found in the same Directory as this Tool)\n"
+ "to generate a Password.\n"
+ "So your first thing to do is to change the "
+ "Master Password.\n"
+ "Click on the Menu \"Edit\" and choose the "
+ "Menu Item \"Change Master Password\".\n\n"
+ "BE AWARE :\n"
+ "You have to write down the new "
+ "Master Password, because this Tool don't save "
+ "the changed Master Password when you close this Tool.\n"
+ "You need the correct Master Password to decrypt a message "
+ "that was encrypted with this Tool, if you don't have the "
+ "correct Master Password, you won't be able to decrypt the message.\n"
+ "Even the NSA or the Author can't help you then.\n"
+ "This is necessary to ensure high security.\n\n"
+ "Next Step is the message, to copy a message from "
+ "another source you have to mark the message, "
+ "right-click and \"copy\" or mark the message and "
+ "use \"STRG+C\" instead, then use the Function in Menu "
+ "\"Edit\" -> \"Paste from Clipboard to Input\" "
+ "or click in the Input-Textfield and use \"STRG+V\" "
+ "to insert the message into the Input Textfield.\n"
+ "Otherwise just write the message in the Input "
+ "Textfield and click on the Button in the AES field \"Encrypt\".\n"
+ "The time to encrypt a message depends on how strong your CPU "
+ "is.\nThe length of the message doesn't really matter "
+ "in AES-Mode, but will in Unique-Mode.\n"
+ "To copy the encrypted message (for the use in other programs) "
+ "you have to use the Function in Menu "
+ "\"Edit\" -> \"Copy Output to Clipboard\".\n\n"
+ "UNIQUE - Encryption:\n"
+ "°°°°°°°°°°°°°°°°°°°°°°°°\n"
+ "It's the same procedure as with AES, but you don't have to "
+ "change the Master Password, because it's not needed in that "
+ "unique Encryption Algorithm.\n"
+ "But you have to read the following important Informations:\n\n"
+ "ATTENTION :\n"
+ "It's not recommended to encrypt messages larger than "
+ "a length of 1.024 chars (spaces included)!\n"
+ "(High CPU-, Memory-/Clipboard-Memory-, consumption!)\n"
+ "Example:\n"
+ "A message, that is 1.024 chars (spaces included) long, "
+ "will produce an encrypted message with a length "
+ "of up to or more than 380.000 chars.\n"
+ "A message with 512 chars will produce an encrypted "
+ "message with a length of up to or more than 220.000 chars.\n"
+ "A message with a single char will produce an "
+ "encrypted message with a length of up to or more "
+ "than 58.000 chars.\n\n"
+ "Even a Quantum Computer in the near future can't crack "
+ "that code, cause to the cosmic number of possibilities:\n\n"
+ "More than 100.000.000.000.000.000.000.000²\n"
+ "possibilities.\n\n"
+ "Decryption - AES & UNIQUE:\n"
+ "°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°\n"
+ "AES only:\n"
+ "First at all, you have to change the Master Password "
+ "to the correct Master Password to decrypt an encrypted "
+ "message.\n\nBoth AES and Unique:\n"
+ "To copy an encrypted message into this Tool "
+ "you have to mark the message and right-click on \"copy\" or "
+ "mark the message and use \"STRG+C\".\nThen use the Function "
+ "in Menu \"Edit\" -> \"Paste from Clipboard to Input\" or "
+ "click on the Input-Textfield and use \"STRG+V\".\n"
+ "Click the Button \"Decrypt\" and you can read the "
+ "message in the Output Textfield.\n\n"
+ "********************************************************\n"
+ " END OF HELP\n"
+ "°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°");
Output.setCaretPosition(0);
}
// Unique Encrypt Button
private void UniqueEncryptActionPerformed(java.awt.event.ActionEvent evt) {
this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
try
{
if(!Input.getText().isEmpty())
{
String temp = Input.getText();
String temp2 = Encryptor.Encrypt(temp.getBytes(UTF_8), P01);
temp = Encryptor.Encrypt(temp2.getBytes(UTF_8), P02);
temp2 = Encryptor.Encrypt(temp.getBytes(UTF_8), P03);
temp = Encryptor.Encrypt(temp2.getBytes(UTF_8), P04);
temp2 = Encryptor.Encrypt(temp.getBytes(UTF_8), P05);
temp = Encryptor.Encrypt(temp2.getBytes(UTF_8), P06);
temp2 = Encryptor.Encrypt(temp.getBytes(UTF_8), P07);
temp = Encryptor.Encrypt(temp2.getBytes(UTF_8), P08);
temp2 = Encryptor.Encrypt(temp.getBytes(UTF_8), P09);
temp = Encryptor.Encrypt(temp2.getBytes(UTF_8), P10);
temp2 = Encryptor.Encrypt(temp.getBytes(UTF_8), P11);
temp = Encryptor.Encrypt(temp2.getBytes(UTF_8), P12);
temp2 = Encryptor.Encrypt(temp.getBytes(UTF_8), P13);
temp = Encryptor.Encrypt(temp2.getBytes(UTF_8), P14);
temp2 = Encryptor.Encrypt(temp.getBytes(UTF_8), P15);
temp = Encryptor.Encrypt(temp2.getBytes(UTF_8), P16);
temp2 = Encryptor.Encrypt(temp.getBytes(UTF_8), P17);
temp = Encryptor.Encrypt(temp2.getBytes(UTF_8), P18);
temp2 = Encryptor.Encrypt(temp.getBytes(UTF_8), P19);
temp = Encryptor.Encrypt(temp2.getBytes(UTF_8), P20);
Output.setText(temp);
}
else
{
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
javax.swing.JOptionPane.showMessageDialog(null, "There is no Text to encrypt!", "Error", javax.swing.JOptionPane.ERROR_MESSAGE);
}
}
catch(Exception ex)
{
Output.setText("An Error occured: " + ex.toString());
}
Output.setCaretPosition(0);
CountInputChars();
CountOutputChars();
}
// Unique Decrypt Button
private void UniqueDecryptActionPerformed(java.awt.event.ActionEvent evt) {
this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
try
{
String test = Input.getText();
if(!test.isEmpty() )
{
String temp = Input.getText();
String temp2 = Decryptor.Decrypt(temp, P20);
temp = Decryptor.Decrypt(temp2, P19);
temp2 = Decryptor.Decrypt(temp, P18);
temp = Decryptor.Decrypt(temp2, P17);
temp2 = Decryptor.Decrypt(temp, P16);
temp = Decryptor.Decrypt(temp2, P15);
temp2 = Decryptor.Decrypt(temp, P14);
temp = Decryptor.Decrypt(temp2, P13);
temp2 = Decryptor.Decrypt(temp, P12);
temp = Decryptor.Decrypt(temp2, P11);
temp2 = Decryptor.Decrypt(temp, P10);
temp = Decryptor.Decrypt(temp2, P09);
temp2 = Decryptor.Decrypt(temp, P08);
temp = Decryptor.Decrypt(temp2, P07);
temp2 = Decryptor.Decrypt(temp, P06);
temp = Decryptor.Decrypt(temp2, P05);
temp2 = Decryptor.Decrypt(temp, P04);
temp = Decryptor.Decrypt(temp2, P03);
temp2 = Decryptor.Decrypt(temp, P02);
temp = Decryptor.Decrypt(temp2, P01);
Output.setText(temp);
}
else
{
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
javax.swing.JOptionPane.showMessageDialog(null, "There is no Text to decrypt!", "Error", javax.swing.JOptionPane.ERROR_MESSAGE);
}
}
catch(Exception ex)
{
Output.setText("An Error occured: " + ex.toString());
grx2++;
}
if(grx2 >= 5)
{
try
{
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
WriteToFile(0, bad);
System.exit(0);
}
catch (Exception ex)
{
javax.swing.JOptionPane.showMessageDialog(null, "An Error occured: " + ex.toString());
}
}
Output.setCaretPosition(0);
CountOutputChars();
}
// Copy Input To Clipboard Button
private void CopyInputButtonActionPerformed(java.awt.event.ActionEvent evt) {
this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
CopyPaste(1);
CountInputChars();
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
// Copy Output To Clipboard Button
private void CopyOutputButtonActionPerformed(java.awt.event.ActionEvent evt) {
this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
CopyPaste(2);
CountOutputChars();
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
// Paste From Clipboard To Input Button
private void PasteClipboardButtonActionPerformed(java.awt.event.ActionEvent evt) {
this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
CopyPaste(3);
CountInputChars();
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
// Input Chars Button
private void InputCharsButtonActionPerformed(java.awt.event.ActionEvent evt) {
CountInputChars();
}
// Output Chars Button
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
CountOutputChars();
}
// Open File
private void OpenFileActionPerformed(java.awt.event.ActionEvent evt) {
int returnVal = FileChooser.showOpenDialog(this);
if(returnVal == JFileChooser.APPROVE_OPTION)
{
File file = FileChooser.getSelectedFile();
try
{
Input.read(new FileReader(file.getAbsolutePath()), null);
}
catch(IOException ex)
{
javax.swing.JOptionPane.showMessageDialog(null, "Error in accessing file:\n\n" + ex + "\n\n" + file.getAbsolutePath(), "ERROR", 0);
}
}
CountInputChars();
}
// Save Input Text To File
private void SaveInputActionPerformed(java.awt.event.ActionEvent evt) {
try
{
WriteToFile(1, null);
}
catch(Exception ex)
{
javax.swing.JOptionPane.showMessageDialog(null, "An Error occured:\n\n" + ex, "ERROR", javax.swing.JOptionPane.ERROR_MESSAGE);
}
}
// Save Output Text To File
private void SaveOutputActionPerformed(java.awt.event.ActionEvent evt) {
try
{
WriteToFile(2, null);
}
catch(Exception ex)
{
javax.swing.JOptionPane.showMessageDialog(null, "An Error occured:\n\n" + ex, "ERROR", javax.swing.JOptionPane.ERROR_MESSAGE);
}
}
// Exit Program
private void ExitActionPerformed(java.awt.event.ActionEvent evt) {
System.exit(0);
}
// Main Function
public static void main(String args[])
{
java.awt.EventQueue.invokeLater(() ->
{
try
{
new METGUI().setVisible(true);
}
catch (Exception ex)
{
Logger.getLogger(METGUI.class.getName()).log(Level.SEVERE, null, ex);
}
});
}
Damit habe ich alles Notwendige reingestellt, auch wenn nicht viele User was damit anfangen können.
Aber es ist die Lösung zu meinem Rätsel. :)
Es ist der komplette Programmcode. ;)