Java - 対称鍵暗号の例

Java –対称キー暗号化の例

Symmetric-Key Cryptographyは、データのエンコードとデコードに同じキーが使用される暗号化システムです。 キーを安全に配布することは、この方法の欠点の1つですが、セキュリティが不足しているため、時間の複雑さが増します。

暗号化アルゴリズムは一般に知られており、「セキュリティを介したセキュリティ」に依存していないと常に仮定する必要があります。 最も一般的な対称アルゴリズムは、DES、Triple-DES、AES、Blowfish、RC2、RC4(ARCFOUR)、RC5、RC6です。

1. 対称キー暗号化の使用例

以下に、対称キー暗号化を使用してプリセットディレクトリを暗号化または復号化するアプリケーションのコードを示します。 コンストラクターは、パスワード、キーの長さ、および暗号に使用されるアルゴリズムで初期化されます。 各アルゴリズムのキーの長さの詳細については、Import Limits on Cryptographic Algorithmsを参照してください。

Note
暗号化アルゴリズムについて詳しく知りたい場合は、Performance Analysis of Data Encryption Algorithms: 2.5 Compared Algorithmsを参照してください。

この例では、AESを使用します。これは、速度とセキュリティの間のシルバーの裏打ちと考えられているためです。

SymmetricKeyExample.java

package com.techfou.symmetric;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import javax.swing.JOptionPane;

public class SymmetricKeyExample {
    private SecretKeySpec secretKey;
    private Cipher cipher;

    public SymmetricKeyExample(String secret, int length, String algorithm)
            throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException {
        byte[] key = new byte[length];
        key = fixSecret(secret, length);
        this.secretKey = new SecretKeySpec(key, algorithm);
        this.cipher = Cipher.getInstance(algorithm);
    }

    private byte[] fixSecret(String s, int length) throws UnsupportedEncodingException {
        if (s.length() < length) {
            int missingLength = length - s.length();
            for (int i = 0; i < missingLength; i++) {
                s += " ";
            }
        }
        return s.substring(0, length).getBytes("UTF-8");
    }

    public void encryptFile(File f)
            throws InvalidKeyException, IOException, IllegalBlockSizeException, BadPaddingException {
        System.out.println("Encrypting file: " + f.getName());
        this.cipher.init(Cipher.ENCRYPT_MODE, this.secretKey);
        this.writeToFile(f);
    }

    public void decryptFile(File f)
            throws InvalidKeyException, IOException, IllegalBlockSizeException, BadPaddingException {
        System.out.println("Decrypting file: " + f.getName());
        this.cipher.init(Cipher.DECRYPT_MODE, this.secretKey);
        this.writeToFile(f);
    }

    public void writeToFile(File f) throws IOException, IllegalBlockSizeException, BadPaddingException {
        FileInputStream in = new FileInputStream(f);
        byte[] input = new byte[(int) f.length()];
        in.read(input);

        FileOutputStream out = new FileOutputStream(f);
        byte[] output = this.cipher.doFinal(input);
        out.write(output);

        out.flush();
        out.close();
        in.close();
    }

    public static void main(String[] args) {
        File dir = new File("src/cryptodir");
        File[] filelist = dir.listFiles();

        SymmetricKeyExample ske;
        try {
            ske = new SymmetricKeyExample("!@#$MySecr3tPassw0rd", 16, "AES");

            int choice = -2;
            while (choice != -1) {
                String[] options = { "Encrypt All", "Decrypt All", "Exit" };
                choice = JOptionPane.showOptionDialog(null, "Select an option", "Options", 0,
                        JOptionPane.QUESTION_MESSAGE, null, options, options[0]);

                switch (choice) {
                case 0:
                    Arrays.asList(filelist).forEach(file -> {
                        try {
                            ske.encryptFile(file);
                        } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException
                                | IOException e) {
                            System.err.println("Couldn't encrypt " + file.getName() + ": " + e.getMessage());
                        }
                    });
                    System.out.println("Files encrypted successfully");
                    break;
                case 1:
                    Arrays.asList(filelist).forEach(file -> {
                        try {
                            ske.decryptFile(file);
                        } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException
                                | IOException e) {
                            System.err.println("Couldn't decrypt " + file.getName() + ": " + e.getMessage());
                        }
                    });
                    System.out.println("Files decrypted successfully");
                    break;
                default:
                    choice = -1;
                    break;
                }
            }
        } catch (UnsupportedEncodingException ex) {
            System.err.println("Couldn't create key: " + ex.getMessage());
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            System.err.println(e.getMessage());
        }
    }
}

出力

java-symmetrickey-output-1

「すべて暗号化」ボタンをクリックすると。

Encrypting file: Hello world.docx
Encrypting file: Hello world.pdf
Encrypting file: Smiley.png
Encrypting file: Text.txt
Files encrypted successfully

「すべてを復号化」ボタンがクリックされたとき。

Decrypting file: Hello world.docx
Decrypting file: Hello world.pdf
Decrypting file: Smiley.png
Decrypting file: Text.txt
Files decrypted successfully

元のテキストファイル。

src/Text.txt

This is a text file.

テキストファイルは暗号化されます。

src/Text.txt

‡(?ê?z@ou7ÿ—pø"é³.Õ0Ò;jVi¶‚

ご注意:このコードを実行する前に、この例の目的だけのために、ファイルを含む別のディレクトリを作成します。 何をしているのか正確にわからない場合は、以下のソースコードをダウンロードしてください。

2. プロジェクトディレクトリ

java-symmetrickey-example

ソースコードをダウンロード