開発者ドキュメント

Java – 非対称暗号化の例

「公開鍵暗号」とも呼ばれる非対称暗号は、2つの異なるが一意に関連する暗号鍵が使用される暗号化システムである。 1つの鍵で暗号化されたデータは、もう一方の鍵で復号化することができます。これらの鍵は、公開鍵と秘密鍵のペアとして知られており、その名前が示すように、公開鍵を配布できる間は秘密鍵は非公開のままでなければなりません。最も一般的な公開鍵アルゴリズムは、RSA、Diffie-Hellman、ElGamal、DSSです。

1.公開鍵と秘密鍵のペアを生成する

プラットフォームに応じて公開鍵と秘密鍵のペアを生成するには、いくつかの方法があります。この例では、Javaを使用してペアを作成します。この例で使用する暗号アルゴリズムはRSAです。

GenerateKeys.java

package com.techfou.keypair;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;

public class GenerateKeys {

    private KeyPairGenerator keyGen;
    private KeyPair pair;
    private PrivateKey privateKey;
    private PublicKey publicKey;

    public GenerateKeys(int keylength) throws NoSuchAlgorithmException, NoSuchProviderException {
        this.keyGen = KeyPairGenerator.getInstance("RSA");
        this.keyGen.initialize(keylength);
    }

    public void createKeys() {
        this.pair = this.keyGen.generateKeyPair();
        this.privateKey = pair.getPrivate();
        this.publicKey = pair.getPublic();
    }

    public PrivateKey getPrivateKey() {
        return this.privateKey;
    }

    public PublicKey getPublicKey() {
        return this.publicKey;
    }

    public void writeToFile(String path, byte[]key) throws IOException {
        File f = new File(path);
        f.getParentFile().mkdirs();

        FileOutputStream fos = new FileOutputStream(f);
        fos.write(key);
        fos.flush();
        fos.close();
    }

    public static void main(String[]args) {
        GenerateKeys gk;
        try {
            gk = new GenerateKeys(1024);
            gk.createKeys();
            gk.writeToFile("KeyPair/publicKey", gk.getPublicKey().getEncoded());
            gk.writeToFile("KeyPair/privateKey", gk.getPrivateKey().getEncoded());
        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
            System.err.println(e.getMessage());
        } catch (IOException e) {
            System.err.println(e.getMessage());
        }

    }

}

出力:



2.暗号化するテキストファイルを作成する



3.鍵ペアを使用してデータを暗号化および復号化する

この例では、公開鍵と秘密鍵をファイルから読み込み、

String`と

File`を暗号化と復号化に使用するクラスを作成します。この例を実行するには、上記のコードを実行してキーを生成するか、以下のソースをダウンロードする必要があります。

AsymmetricCryptography.java

package com.techfou.asymmetric;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.file.Files;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.apache.commons.codec.binary.Base64;

public class AsymmetricCryptography {
    private Cipher cipher;

    public AsymmetricCryptography() throws NoSuchAlgorithmException, NoSuchPaddingException {
        this.cipher = Cipher.getInstance("RSA");
    }

   //https://docs.oracle.com/javase/8/docs/api/java/security/spec/PKCS8EncodedKeySpec.html
    public PrivateKey getPrivate(String filename) throws Exception {
        byte[]keyBytes = Files.readAllBytes(new File(filename).toPath());
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePrivate(spec);
    }

   //https://docs.oracle.com/javase/8/docs/api/java/security/spec/X509EncodedKeySpec.html
    public PublicKey getPublic(String filename) throws Exception {
        byte[]keyBytes = Files.readAllBytes(new File(filename).toPath());
        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePublic(spec);
    }

    public void encryptFile(byte[]input, File output, PrivateKey key)
        throws IOException, GeneralSecurityException {
        this.cipher.init(Cipher.ENCRYPT__MODE, key);
        writeToFile(output, this.cipher.doFinal(input));
    }

    public void decryptFile(byte[]input, File output, PublicKey key)
        throws IOException, GeneralSecurityException {
        this.cipher.init(Cipher.DECRYPT__MODE, key);
        writeToFile(output, this.cipher.doFinal(input));
    }

    private void writeToFile(File output, byte[]toWrite)
            throws IllegalBlockSizeException, BadPaddingException, IOException {
        FileOutputStream fos = new FileOutputStream(output);
        fos.write(toWrite);
        fos.flush();
        fos.close();
    }

    public String encryptText(String msg, PrivateKey key)
            throws NoSuchAlgorithmException, NoSuchPaddingException,
            UnsupportedEncodingException, IllegalBlockSizeException,
            BadPaddingException, InvalidKeyException {
        this.cipher.init(Cipher.ENCRYPT__MODE, key);
        return Base64.encodeBase64String(cipher.doFinal(msg.getBytes("UTF-8")));
    }

    public String decryptText(String msg, PublicKey key)
            throws InvalidKeyException, UnsupportedEncodingException,
            IllegalBlockSizeException, BadPaddingException {
        this.cipher.init(Cipher.DECRYPT__MODE, key);
        return new String(cipher.doFinal(Base64.decodeBase64(msg)), "UTF-8");
    }

    public byte[]getFileInBytes(File f) throws IOException {
        FileInputStream fis = new FileInputStream(f);
        byte[]fbytes = new byte[(int) f.length()];
        fis.read(fbytes);
        fis.close();
        return fbytes;
    }

    public static void main(String[]args) throws Exception {
        AsymmetricCryptography ac = new AsymmetricCryptography();
        PrivateKey privateKey = ac.getPrivate("KeyPair/privateKey");
        PublicKey publicKey = ac.getPublic("KeyPair/publicKey");

        String msg = "Cryptography is fun!";
        String encrypted__msg = ac.encryptText(msg, privateKey);
        String decrypted__msg = ac.decryptText(encrypted__msg, publicKey);
        System.out.println("Original Message: " + msg +
            "\nEncrypted Message: " + encrypted__msg
            + "\nDecrypted Message: " + decrypted__msg);

        if (new File("KeyPair/text.txt").exists()) {
            ac.encryptFile(ac.getFileInBytes(new File("KeyPair/text.txt")),
                new File("KeyPair/text__encrypted.txt"),privateKey);
            ac.decryptFile(ac.getFileInBytes(new File("KeyPair/text__encrypted.txt")),
                new File("KeyPair/text__decrypted.txt"), publicKey);
        } else {
            System.out.println("Create a file text.txt under folder KeyPair");
        }
    }
}

出力:

Original Message: Cryptography is fun!

Encrypted Message: NZY+9v4AWoADVBQiFmS8ake6dG8M9v4WDf4TSPKgGPoKeJtHxEWVFGFL57qR2mbuknn8WYjfjcN+BA/  RDsDQ9Q5SxQFLi8GE7A/6fdURjO+Vz3qYFaefpXccp7SnObKXnFfUNp00m5BtMSdTLEYfngF9UDBVYVFz0EZwuyP50xY=

Decrypted Message: Cryptography is fun!

暗号化されたテキスト:



復号化されたテキスト:



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

ダウンロードする – リンク://wp-content/uploads/2016/11/AsymmetricCryptographyExample.zip[AsymmetricCryptographyExample.zip(5KB)]

参考文献

非対称鍵暗号アルゴリズムの研究]。

https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator

[KeyPairGenerator

アルゴリズム]

リンク://タグ/非対称/[非対称]リンク://タグ/暗号//[暗号]リンク://タグ/暗号化/[暗号化]リンク://タグ/java-security/[java
セキュリティ]リンク://タグ/公開鍵/[公開鍵]リンク://タグ/rsa/[rsa]

モバイルバージョンを終了